Skip to content

Commit a8cf20e

Browse files
committed
wip
1 parent fb98874 commit a8cf20e

File tree

12 files changed

+1808
-1002
lines changed

12 files changed

+1808
-1002
lines changed

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope
7777

7878
override AstNode getChildNode(int i) {
7979
i = 0 and
80-
result = this.getParamList().getSelfParam()
80+
result = this.getSelfParam()
8181
or
8282
result = this.getParam(i - 1)
8383
or

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ module Impl {
102102
f = resolvePath(path) and
103103
path.getSegment().getIdentifier().getText() = methodName and
104104
exists(SelfParam self |
105-
self = f.getParamList().getSelfParam() and
105+
self = f.getSelfParam() and
106106
if self.isRef() then selfIsRef = true else selfIsRef = false
107107
)
108108
)

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,15 @@ module Impl {
1717
*/
1818
class Callable extends Generated::Callable {
1919
override Param getParam(int index) { result = this.getParamList().getParam(index) }
20+
21+
/**
22+
* Gets the self parameter of this callable, if it exists.
23+
*/
24+
SelfParam getSelfParam() { result = this.getParamList().getSelfParam() }
25+
26+
/**
27+
* Holds if `getSelfParam()` exists.
28+
*/
29+
predicate hasSelfParam() { exists(this.getSelfParam()) }
2030
}
2131
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
1212
* the canonical path `path` and the method name `method`, and if it borrows its
1313
* first `borrows` arguments.
1414
*/
15-
private predicate isOverloaded(string op, int arity, string path, string method, int borrows) {
15+
predicate isOverloaded(string op, int arity, string path, string method, int borrows) {
1616
arity = 1 and
1717
(
1818
// Negation

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ module Impl {
2121
* ```
2222
*/
2323
class Union extends Generated::Union {
24+
/** Gets the record field named `name`, if any. */
25+
pragma[nomagic]
26+
StructField getStructField(string name) {
27+
result = this.getStructFieldList().getAField() and
28+
result.getName().getText() = name
29+
}
30+
2431
override string toStringImpl() { result = "union " + this.getName().getText() }
2532
}
2633
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ module Impl {
109109
text = name.getText() and
110110
// exclude self parameters from functions without a body as these are
111111
// trait method declarations without implementations
112-
not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp)
112+
not exists(Function f | not f.hasBody() and f.getSelfParam() = sp)
113113
)
114114
or
115115
exists(IdentPat pat |

rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,43 @@ class StringStruct extends Struct {
213213
pragma[nomagic]
214214
StringStruct() { this.getCanonicalPath() = "alloc::string::String" }
215215
}
216+
217+
/**
218+
* The [`Deref` trait][1].
219+
*
220+
* [1]: https://doc.rust-lang.org/core/ops/trait.Deref.html
221+
*/
222+
class DerefTrait extends Trait {
223+
pragma[nomagic]
224+
DerefTrait() { this.getCanonicalPath() = "core::ops::deref::Deref" }
225+
226+
/** Gets the `deref` function. */
227+
Function getDerefFunction() { result = this.(TraitItemNode).getAssocItem("deref") }
228+
229+
/** Gets the `Target` associated type. */
230+
pragma[nomagic]
231+
TypeAlias getTargetType() {
232+
result = this.getAssocItemList().getAnAssocItem() and
233+
result.getName().getText() = "Target"
234+
}
235+
}
236+
237+
/**
238+
* The [`Index` trait][1].
239+
*
240+
* [1]: https://doc.rust-lang.org/std/ops/trait.Index.html
241+
*/
242+
class IndexTrait extends Trait {
243+
pragma[nomagic]
244+
IndexTrait() { this.getCanonicalPath() = "core::ops::index::Index" }
245+
246+
/** Gets the `index` function. */
247+
Function getIndexFunction() { result = this.(TraitItemNode).getAssocItem("index") }
248+
249+
/** Gets the `Output` associated type. */
250+
pragma[nomagic]
251+
TypeAlias getOutputType() {
252+
result = this.getAssocItemList().getAnAssocItem() and
253+
result.getName().getText() = "Output"
254+
}
255+
}

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

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,8 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
636636

637637
TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) }
638638

639+
predicate isBlanket() { this.resolveSelfTy() instanceof TypeParam }
640+
639641
override AssocItemNode getAnAssocItem() { result = this.getADescendant() }
640642

641643
override string getName() { result = "(impl)" }
@@ -721,7 +723,7 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
721723
}
722724
}
723725

724-
final private class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTraitTypeRepr {
726+
final class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTraitTypeRepr {
725727
pragma[nomagic]
726728
Path getABoundPath() {
727729
result = super.getTypeBoundList().getABound().getTypeRepr().(PathTypeRepr).getPath()
@@ -1425,24 +1427,56 @@ signature predicate relevantTraitVisibleSig(Element element, Trait trait);
14251427
* at a given element.
14261428
*/
14271429
module TraitIsVisible<relevantTraitVisibleSig/2 relevantTraitVisible> {
1428-
/** Holds if the trait might be looked up in `encl`. */
1429-
private predicate traitLookup(ItemNode encl, Element element, Trait trait) {
1430-
// lookup in immediately enclosing item
1431-
relevantTraitVisible(element, trait) and
1432-
encl.getADescendant() = element
1430+
private newtype TNode =
1431+
TTrait(Trait t) { relevantTraitVisible(_, t) } or
1432+
TItemNode(ItemNode i) or
1433+
TElement(Element e) { relevantTraitVisible(e, _) }
1434+
1435+
private predicate isTrait(TNode n) { n instanceof TTrait }
1436+
1437+
private predicate step(TNode n1, TNode n2) {
1438+
exists(Trait t1, ItemNode i2 |
1439+
n1 = TTrait(t1) and
1440+
n2 = TItemNode(i2) and
1441+
t1 = i2.getASuccessor(_, _)
1442+
)
14331443
or
1434-
// lookup in an outer scope, but only if the trait is not declared in inner scope
1435-
exists(ItemNode mid |
1436-
traitLookup(mid, element, trait) and
1437-
not trait = mid.getASuccessor(_, _) and
1438-
encl = getOuterScope(mid)
1444+
exists(ItemNode i1, ItemNode i2 |
1445+
n1 = TItemNode(i1) and
1446+
n2 = TItemNode(i2) and
1447+
i1 = getOuterScope(i2)
1448+
)
1449+
or
1450+
exists(ItemNode i1, Element e2 |
1451+
n1 = TItemNode(i1) and
1452+
n2 = TElement(e2) and
1453+
i1.getADescendant() = e2
1454+
)
1455+
}
1456+
1457+
private predicate isElement(TNode n) { n instanceof TElement }
1458+
1459+
private predicate traitIsVisibleTC(TNode trait, TNode element) =
1460+
doublyBoundedFastTC(step/2, isTrait/1, isElement/1)(trait, element)
1461+
1462+
pragma[nomagic]
1463+
private predicate relevantTraitVisibleLift(TNode trait, TElement element) {
1464+
exists(Trait t, Element e |
1465+
trait = TTrait(t) and
1466+
element = TElement(e) and
1467+
relevantTraitVisible(e, t)
14391468
)
14401469
}
14411470

14421471
/** Holds if the trait `trait` is visible at `element`. */
14431472
pragma[nomagic]
14441473
predicate traitIsVisible(Element element, Trait trait) {
1445-
exists(ItemNode encl | traitLookup(encl, element, trait) and trait = encl.getASuccessor(_, _))
1474+
exists(TNode t, TNode e |
1475+
traitIsVisibleTC(t, e) and
1476+
relevantTraitVisibleLift(t, e) and
1477+
t = TTrait(trait) and
1478+
e = TElement(element)
1479+
)
14461480
}
14471481
}
14481482

@@ -1740,7 +1774,7 @@ private module Debug {
17401774
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
17411775
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
17421776
filepath.matches("%/main.rs") and
1743-
startline = 52
1777+
startline = 167
17441778
)
17451779
}
17461780

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

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ newtype TType =
4242
TStruct(Struct s) or
4343
TEnum(Enum e) or
4444
TTrait(Trait t) or
45+
TUnion(Union u) or
4546
TArrayType() or // todo: add size?
4647
TRefType() or // todo: add mut?
4748
TImplTraitType(ImplTraitTypeRepr impl) or
4849
TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or
4950
TSliceType() or
51+
TNeverType() or
52+
TPtrType() or
5053
TTupleTypeParameter(int arity, int i) { exists(TTuple(arity)) and i in [0 .. arity - 1] } or
5154
TTypeParamTypeParameter(TypeParam t) or
5255
TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or
@@ -57,7 +60,8 @@ newtype TType =
5760
} or
5861
TRefTypeParameter() or
5962
TSelfTypeParameter(Trait t) or
60-
TSliceTypeParameter()
63+
TSliceTypeParameter() or
64+
TPtrTypeParameter()
6165

6266
private predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) {
6367
implTrait.isInReturnPos() and
@@ -224,6 +228,31 @@ class TraitType extends Type, TTrait {
224228
override Location getLocation() { result = trait.getLocation() }
225229
}
226230

231+
/** A union type. */
232+
class UnionType extends StructOrEnumType, TUnion {
233+
private Union union;
234+
235+
UnionType() { this = TUnion(union) }
236+
237+
override ItemNode asItemNode() { result = union }
238+
239+
override StructField getStructField(string name) { result = union.getStructField(name) }
240+
241+
override TupleField getTupleField(int i) { none() }
242+
243+
override TypeParameter getPositionalTypeParameter(int i) {
244+
result = TTypeParamTypeParameter(union.getGenericParamList().getTypeParam(i))
245+
}
246+
247+
override TypeMention getTypeParameterDefault(int i) {
248+
result = union.getGenericParamList().getTypeParam(i).getDefaultType()
249+
}
250+
251+
override string toString() { result = union.getName().getText() }
252+
253+
override Location getLocation() { result = union.getLocation() }
254+
}
255+
227256
/**
228257
* An array type.
229258
*
@@ -374,6 +403,33 @@ class SliceType extends Type, TSliceType {
374403
override Location getLocation() { result instanceof EmptyLocation }
375404
}
376405

406+
class NeverType extends Type, TNeverType {
407+
override StructField getStructField(string name) { none() }
408+
409+
override TupleField getTupleField(int i) { none() }
410+
411+
override TypeParameter getPositionalTypeParameter(int i) { none() }
412+
413+
override string toString() { result = "!" }
414+
415+
override Location getLocation() { result instanceof EmptyLocation }
416+
}
417+
418+
class PtrType extends Type, TPtrType {
419+
override StructField getStructField(string name) { none() }
420+
421+
override TupleField getTupleField(int i) { none() }
422+
423+
override TypeParameter getPositionalTypeParameter(int i) {
424+
i = 0 and
425+
result = TPtrTypeParameter()
426+
}
427+
428+
override string toString() { result = "*" }
429+
430+
override Location getLocation() { result instanceof EmptyLocation }
431+
}
432+
377433
/** A type parameter. */
378434
abstract class TypeParameter extends Type {
379435
override StructField getStructField(string name) { none() }
@@ -529,6 +585,12 @@ class SliceTypeParameter extends TypeParameter, TSliceTypeParameter {
529585
override Location getLocation() { result instanceof EmptyLocation }
530586
}
531587

588+
class PtrTypeParameter extends TypeParameter, TPtrTypeParameter {
589+
override string toString() { result = "*T" }
590+
591+
override Location getLocation() { result instanceof EmptyLocation }
592+
}
593+
532594
/**
533595
* The implicit `Self` type parameter of a trait, that refers to the
534596
* implementing type of the trait.

0 commit comments

Comments
 (0)