Skip to content

Commit 33482c4

Browse files
committed
wip
1 parent adfced0 commit 33482c4

File tree

4 files changed

+81
-51
lines changed

4 files changed

+81
-51
lines changed

rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,8 @@ module Impl {
6969
this.getLocation().getStartLine() <= result.getLocation().getStartLine() and
7070
result.getLocation().getStartLine() <= this.getName().getLocation().getStartLine()
7171
}
72+
73+
pragma[nomagic]
74+
predicate hasSelfParam() { this.getParamList().hasSelfParam() }
7275
}
7376
}

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 78 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ class FunctionPosition extends TFunctionPosition {
773773
this.isReturn() and
774774
result = this
775775
or
776-
if f.getParamList().hasSelfParam()
776+
if f.hasSelfParam()
777777
then
778778
this.isSelf() and result.asPositional() = 0
779779
or
@@ -870,6 +870,8 @@ private module FunctionOverloading {
870870
* Holds if type parameter `tp` of `trait` occurs in the function with the name
871871
* `functionName` at the `pos`th parameter at `path`.
872872
*
873+
* TODO: Update
874+
*
873875
* The special position `-1` refers to the return type of the function, which
874876
* is sometimes needed to disambiguate associated function calls like
875877
* `Default::default()` (in this case, `tp` is the special `Self` type parameter).
@@ -951,7 +953,7 @@ private newtype TFunctionPositionType =
951953
MkFunctionPositionType(Function f, FunctionPosition pos, ImplOrTraitItemNode i) {
952954
f = i.getAnAssocItem() and
953955
(
954-
f.getParamList().hasSelfParam() and
956+
f.hasSelfParam() and
955957
pos.asArgumentPosition().isSelf()
956958
or
957959
exists(f.getParam(pos.asPositional()))
@@ -1083,7 +1085,7 @@ private class FunctionPositionType extends TFunctionPositionType {
10831085
result = f.getParam(pos.asPositional())
10841086
or
10851087
pos.isReturn() and
1086-
result = f.getRetType()
1088+
result = f.getRetType().getTypeRepr()
10871089
)
10881090
}
10891091

@@ -1107,7 +1109,8 @@ private module MethodCallResolution {
11071109
*/
11081110
pragma[nomagic]
11091111
predicate methodCandidate(
1110-
Type type, string name, int arity, ImplOrTraitItemNode i, FunctionPositionType self
1112+
Type type, string name, int arity, ImplOrTraitItemNode i, FunctionPositionType self,
1113+
Type selfType
11111114
) {
11121115
exists(Function f, FunctionPosition pos |
11131116
f = i.getASuccessor(name) and
@@ -1116,13 +1119,17 @@ private module MethodCallResolution {
11161119
self.appliesTo(f, pos, i) and
11171120
pos.isSelf() and
11181121
not i.(ImplItemNode).isBlanket()
1122+
|
1123+
selfType = i.(Impl).getSelfTy().(TypeMention).resolveType()
1124+
or
1125+
selfType = TTrait(i)
11191126
)
11201127
}
11211128

11221129
pragma[nomagic]
11231130
private predicate methodCandidateImplTrait(string name, int arity, Trait trait) {
11241131
exists(ImplItemNode i |
1125-
methodCandidate(_, name, arity, i, _) and
1132+
methodCandidate(_, name, arity, i, _, _) and
11261133
trait = i.resolveTraitTy()
11271134
)
11281135
}
@@ -1151,7 +1158,7 @@ private module MethodCallResolution {
11511158
) {
11521159
exists(string name, int arity |
11531160
mc.isMethodCall(name, arity) and
1154-
methodCandidate(type, name, arity, i, self) //and
1161+
methodCandidate(type, name, arity, i, self, _) //and
11551162
|
11561163
// not CertainTypeInference::inferCertainType(mc.getReceiver(), TypePath::nil()) != type
11571164
not exists(i.(ImplItemNode).resolveTraitTy())
@@ -1389,7 +1396,7 @@ private module MethodCallResolution {
13891396
exists(Type type, string name, int arity |
13901397
this.isMethodCall(_, type, name, arity) and
13911398
forall(Impl impl |
1392-
methodCandidate(type, name, arity, impl, _) and
1399+
methodCandidate(type, name, arity, impl, _, _) and
13931400
not impl.hasTrait()
13941401
|
13951402
this.isNotInherentTarget(impl)
@@ -1656,22 +1663,37 @@ private module FunctionCallResolution {
16561663

16571664
/** A function call, `f(x)`. */
16581665
final class FunctionCall extends CallExpr {
1659-
// FunctionCall() { this = Debug::getRelevantLocatable() }
1660-
private ItemNode getResolvedFunction() { result = CallExprImpl::getResolvedFunction(this) }
1666+
private ItemNode getPathResolutionResolvedFunction() {
1667+
result = CallExprImpl::getResolvedFunction(this)
1668+
}
1669+
1670+
// The `Self` type is supplied explicitly as a type qualifier, e.g. `Foo::<Bar>::baz()`
1671+
pragma[nomagic]
1672+
Type getQualifierType(TypePath path) {
1673+
exists(PathExpr pe, TypeMention tm |
1674+
pe = this.getFunction() and
1675+
tm = pe.getPath().getQualifier() and
1676+
result = tm.resolveTypeAt(path) and
1677+
not resolvePath(tm) instanceof Trait
1678+
)
1679+
}
16611680

16621681
/**
16631682
* Holds if the target of this call is ambigous, and type information is required
16641683
* to disambiguate.
16651684
*/
1666-
predicate isAmbigous() {
1685+
private predicate isAmbigous() {
16671686
this.(Call).hasTrait()
16681687
or
1669-
functionResolutionDependsOnArgument(_, _, this.getResolvedFunction(), _, _, _)
1688+
functionResolutionDependsOnArgument(_, _, this.getPathResolutionResolvedFunction(), _, _, _)
16701689
}
16711690

16721691
pragma[nomagic]
1673-
Function getAnAmbigousCandidate0(ImplItemNode impl, FunctionPosition pos, Function resolved) {
1674-
resolved = this.getResolvedFunction() and
1692+
Function getAnAmbigousCandidate0(
1693+
ImplOrTraitItemNode impl, FunctionPosition pos, Function resolved
1694+
) {
1695+
// this = Debug::getRelevantLocatable() and
1696+
resolved = this.getPathResolutionResolvedFunction() and
16751697
(
16761698
exists(TraitItemNode trait |
16771699
trait = this.(Call).getTrait() and
@@ -1680,16 +1702,25 @@ private module FunctionCallResolution {
16801702
|
16811703
functionResolutionDependsOnArgument(impl, _, result, pos, _, _)
16821704
or
1683-
exists(TypeParameter tp | traitTypeParameterOccurrence(trait, resolved, _, pos, _, tp) |
1684-
not pos.isReturn()
1685-
or
1686-
// We only check that the context of the call provides relevant type information
1687-
// when no argument can
1688-
not traitTypeParameterOccurrence(trait, resolved, _,
1689-
any(FunctionPosition pos0 | not pos0.isReturn()), _, _)
1690-
)
1705+
if resolved.hasSelfParam()
1706+
then
1707+
// always check the `self` type in method calls
1708+
pos.isSelf()
1709+
else
1710+
// todo: remove tp
1711+
exists(TypeParameter tp | traitTypeParameterOccurrence(trait, resolved, _, pos, _, tp) |
1712+
not pos.isReturn()
1713+
or
1714+
// We only check that the context of the call provides relevant type information
1715+
// when no argument can
1716+
not exists(FunctionPosition pos0 |
1717+
traitTypeParameterOccurrence(trait, resolved, _, pos0, _, tp) and
1718+
not pos0.isReturn()
1719+
)
1720+
)
16911721
)
16921722
or
1723+
not this.(Call).hasTrait() and
16931724
result = resolved and
16941725
functionResolutionDependsOnArgument(impl, _, result, pos, _, _)
16951726
)
@@ -1704,7 +1735,9 @@ private module FunctionCallResolution {
17041735
* `resolved` is the corresponding function resolved through path resolution.
17051736
*/
17061737
pragma[nomagic]
1707-
Function getAnAmbigousCandidate(ImplItemNode impl, FunctionPosition pos, Function resolved) {
1738+
Function getAnAmbigousCandidate(
1739+
ImplOrTraitItemNode impl, FunctionPosition pos, Function resolved
1740+
) {
17081741
exists(FunctionPosition pos0 |
17091742
result = this.getAnAmbigousCandidate0(impl, pos0, resolved) and
17101743
pos = pos0.getFunctionCallAdjusted(result)
@@ -1715,7 +1748,7 @@ private module FunctionCallResolution {
17151748
* Same as `getAnAmbigousCandidate`, ranks the positions to be checked.
17161749
*/
17171750
private Function getAnAmbigousCandidateRanked(
1718-
ImplItemNode impl, FunctionPosition pos, Function f, int rnk
1751+
ImplOrTraitItemNode impl, FunctionPosition pos, Function f, int rnk
17191752
) {
17201753
pos =
17211754
rank[rnk + 1](FunctionPosition pos0, int i1, int i2 |
@@ -1732,7 +1765,7 @@ private module FunctionCallResolution {
17321765

17331766
pragma[nomagic]
17341767
private Function resolveAmbigousFunctionCallTargetFromIndex(int index) {
1735-
exists(Impl impl, FunctionPosition pos, Function resolved |
1768+
exists(ImplOrTraitItemNode impl, FunctionPosition pos, Function resolved |
17361769
IsInstantiationOf<AmbigousFunctionCall, FunctionPositionType, AmbigousFuncIsInstantiationOfInput>::isInstantiationOf(MkAmbigousFunctionCall(this,
17371770
resolved, pos), impl, _) and
17381771
result = this.getAnAmbigousCandidateRanked(impl, pos, resolved, index)
@@ -1759,7 +1792,7 @@ private module FunctionCallResolution {
17591792
*/
17601793
pragma[nomagic]
17611794
private ItemNode resolveUnambigousFunctionCallTarget() {
1762-
result = this.getResolvedFunction() and
1795+
result = this.getPathResolutionResolvedFunction() and
17631796
not this.isAmbigous()
17641797
}
17651798

@@ -1785,13 +1818,24 @@ private module FunctionCallResolution {
17851818
AmbigousFunctionCall() { this = MkAmbigousFunctionCall(call, resolved, pos) }
17861819

17871820
pragma[nomagic]
1788-
Type getTypeAt(TypePath path) {
1821+
private Type getTypeAt0(TypePath path) {
17891822
result = inferType(call.(CallExpr).getArg(pos.asPositional()), path)
17901823
or
1824+
// pos.asPositional() = 0 and
1825+
// result = call.getQualifierType(path)
1826+
// or
17911827
pos.isReturn() and
17921828
result = inferType(call, path)
17931829
}
17941830

1831+
pragma[nomagic]
1832+
Type getTypeAt(TypePath path) {
1833+
result = this.getTypeAt0(path) and
1834+
not exists(getATraitBound(result))
1835+
or
1836+
result = TTrait(getATraitBound(this.getTypeAt0(path)))
1837+
}
1838+
17951839
string toString() { result = call.toString() + " (pos: " + pos + ")" }
17961840

17971841
Location getLocation() { result = call.getLocation() }
@@ -1937,9 +1981,7 @@ private module FunctionCallMatchingInput implements MatchingInputSig {
19371981
exists(Param p, int i |
19381982
p = this.getParam(i) and
19391983
result = p.getTypeRepr().(TypeMention).resolveTypeAt(path) and
1940-
if this.getParamList().hasSelfParam()
1941-
then dpos.asPositional() = i + 1
1942-
else dpos.asPositional() = i
1984+
if this.hasSelfParam() then dpos.asPositional() = i + 1 else dpos.asPositional() = i
19431985
)
19441986
or
19451987
dpos.asPositional() = 0 and
@@ -1992,14 +2034,8 @@ private module FunctionCallMatchingInput implements MatchingInputSig {
19922034

19932035
pragma[nomagic]
19942036
Type getInferredType(AccessPosition apos, TypePath path) {
1995-
// The `Self` type is supplied explicitly as a type qualifier, e.g. `Foo::<Bar>::baz()`
19962037
apos.asArgumentPosition().isSelf() and
1997-
exists(PathExpr pe, TypeMention tm |
1998-
pe = this.getFunction() and
1999-
tm = pe.getPath().getQualifier() and
2000-
result = tm.resolveTypeAt(path) and
2001-
not resolvePath(tm) instanceof Trait
2002-
)
2038+
result = this.getQualifierType(path)
20032039
or
20042040
result = inferType(this.getNodeAt(apos), path)
20052041
}
@@ -2028,6 +2064,7 @@ private Type inferCallExprType(AstNode n, TypePath path) {
20282064
private module OperationResolution {
20292065
/** An operation, `x + y`. */
20302066
final class Op extends Operation {
2067+
// Op() { none() }
20312068
pragma[nomagic]
20322069
private Type getTypeAt0(TypePath path) {
20332070
if this.(Call).implicitBorrowAt(any(ArgumentPosition pos | pos.isSelf()), true)
@@ -2099,7 +2136,7 @@ private module OperationResolution {
20992136
Type type, Trait trait, string name, int arity, ImplOrTraitItemNode i,
21002137
FunctionPositionType self
21012138
) {
2102-
MethodCallResolution::methodCandidate(type, name, arity, i, self) and
2139+
MethodCallResolution::methodCandidate(type, name, arity, i, self, _) and
21032140
(
21042141
trait = i.(ImplItemNode).resolveTraitTy()
21052142
or
@@ -2109,9 +2146,10 @@ private module OperationResolution {
21092146

21102147
pragma[nomagic]
21112148
predicate potentialInstantiationOf(Op op, TypeAbstraction abs, FunctionPositionType constraint) {
2112-
exists(Type type, Trait trait, string name, int arity |
2149+
exists(Type type, Trait trait, string name, int arity, Type selfType |
21132150
op.isOperation(type, trait, name, arity) and
2114-
MethodCallResolution::methodCandidate(type, name, arity, abs, constraint)
2151+
MethodCallResolution::methodCandidate(type, name, arity, abs, constraint, selfType) and
2152+
op.getTypeAt(_) = selfType
21152153
|
21162154
trait = abs.(ImplItemNode).resolveTraitTy()
21172155
or
@@ -3035,7 +3073,7 @@ private module Debug {
30353073
// filepath.matches("%/crates/wdk-macros/src/lib.rs") and
30363074
// endline = [255 .. 256]
30373075
filepath.matches("%/main.rs") and
3038-
startline = 2318
3076+
startline = 120
30393077
)
30403078
}
30413079

rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,7 @@ multipleCallTargets
1010
| test.rs:169:26:169:111 | ...::_print(...) |
1111
| test.rs:179:30:179:68 | ...::_print(...) |
1212
| test.rs:188:26:188:105 | ...::_print(...) |
13-
| test.rs:217:22:217:62 | ... .read_to_end(...) |
14-
| test.rs:223:22:223:65 | ... .read_to_string(...) |
1513
| test.rs:229:22:229:72 | ... .read_to_string(...) |
16-
| test.rs:235:9:235:48 | ... .read_exact(...) |
17-
| test.rs:513:22:513:50 | file.read_to_end(...) |
18-
| test.rs:519:22:519:53 | file.read_to_string(...) |
1914
| test.rs:639:26:639:43 | file1.chain(...) |
2015
| test.rs:647:26:647:40 | file1.take(...) |
2116
| test.rs:697:18:697:38 | ...::_print(...) |

rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
| test.rs:319:14:319:20 | &buffer | Fixed missing result: hasTaintFlow |
2-
| test.rs:326:14:326:20 | &buffer | Fixed missing result: hasTaintFlow |
3-
| test.rs:333:14:333:20 | &buffer | Fixed missing result: hasTaintFlow |
4-
| test.rs:592:14:592:20 | &buffer | Fixed missing result: hasTaintFlow="file.txt" |
5-
| test.rs:598:14:598:20 | &buffer | Fixed missing result: hasTaintFlow="file.txt" |
6-
| test.rs:604:14:604:20 | &buffer | Fixed missing result: hasTaintFlow="file.txt" |
71
| test.rs:641:14:641:20 | &buffer | Fixed missing result: hasTaintFlow="another_file.txt" |
82
| test.rs:641:14:641:20 | &buffer | Fixed missing result: hasTaintFlow="file.txt" |
93
| test.rs:649:14:649:20 | &buffer | Fixed missing result: hasTaintFlow="file.txt" |

0 commit comments

Comments
 (0)