Skip to content

Commit 46f5d89

Browse files
committed
Rust: Handle builtin types in path resolution
1 parent 39720a1 commit 46f5d89

File tree

14 files changed

+2618
-2478
lines changed

14 files changed

+2618
-2478
lines changed

rust/ql/lib/codeql/rust/dataflow/internal/Content.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
private import rust
66
private import codeql.rust.controlflow.CfgNodes
7+
private import codeql.rust.frameworks.stdlib.Builtins
78
private import DataFlowImpl
89

910
/**
@@ -36,7 +37,11 @@ class TupleFieldContent extends FieldContent, TTupleFieldContent {
3637
/** Holds if this field belongs to a struct. */
3738
predicate isStructField(Struct s, int pos) { field.isStructField(s, pos) }
3839

39-
override FieldExprCfgNode getAnAccess() { field = result.getFieldExpr().getTupleField() }
40+
override FieldExprCfgNode getAnAccess() {
41+
field = result.getFieldExpr().getTupleField() and
42+
// tuples are handled using the special `TupleContent` type
43+
not field = any(TupleType tt).getATupleField()
44+
}
4045

4146
final override string toString() {
4247
exists(Variant v, int pos, string vname |

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ module Impl {
3232
result.getName().getText() = name
3333
}
3434

35+
/** Gets a record field, if any. */
36+
StructField getAStructField() { result = this.getStructField(_) }
37+
3538
/** Gets the `i`th tuple field, if any. */
3639
pragma[nomagic]
3740
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }
3841

42+
/** Gets a tuple field, if any. */
43+
TupleField getATupleField() { result = this.getTupleField(_) }
44+
3945
/** Holds if this struct uses tuple fields. */
4046
pragma[nomagic]
4147
predicate isTuple() { this.getFieldList() instanceof TupleFieldList }

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,36 @@ class F32 extends FloatingPointTypeImpl {
136136
class F64 extends FloatingPointTypeImpl {
137137
F64() { this.getName() = "f64" }
138138
}
139+
140+
/** The builtin slice type `[T]`. */
141+
class SliceType extends BuiltinType {
142+
SliceType() { this.getName() = "Slice" }
143+
}
144+
145+
/** The builtin array type `[T; N]`. */
146+
class ArrayType extends BuiltinType {
147+
ArrayType() { this.getName() = "Array" }
148+
}
149+
150+
/** The builtin reference type `&T` or `&mut T`. */
151+
class RefType extends BuiltinType {
152+
RefType() { this.getName() = "Ref" }
153+
}
154+
155+
/** The builtin pointer type `*const T` or `*mut T`. */
156+
class PtrType extends BuiltinType {
157+
PtrType() { this.getName() = "Ptr" }
158+
}
159+
160+
/** A builtin tuple type `(T1, T2, ...)`. */
161+
class TupleType extends BuiltinType {
162+
TupleType() { this.getName().matches("Tuple%") }
163+
164+
/** Gets the arity of this tuple type. */
165+
int getArity() {
166+
not this.hasGenericParamList() and
167+
result = 0
168+
or
169+
result = this.getGenericParamList().getNumberOfGenericParams()
170+
}
171+
}

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -713,12 +713,34 @@ abstract class ImplOrTraitItemNode extends ItemNode {
713713
predicate hasAssocItem(string name) { name = this.getAnAssocItem().getName() }
714714
}
715715

716+
private TypeItemNode resolveBuiltin(TypeRepr tr) {
717+
tr instanceof SliceTypeRepr and
718+
result instanceof Builtins::SliceType
719+
or
720+
tr instanceof ArrayTypeRepr and
721+
result instanceof Builtins::ArrayType
722+
or
723+
tr instanceof RefTypeRepr and
724+
result instanceof Builtins::RefType
725+
or
726+
tr instanceof PtrTypeRepr and
727+
result instanceof Builtins::PtrType
728+
or
729+
result.(Builtins::TupleType).getArity() = tr.(TupleTypeRepr).getNumberOfFields()
730+
}
731+
716732
final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
717733
Path getSelfPath() { result = super.getSelfTy().(PathTypeRepr).getPath() }
718734

719735
Path getTraitPath() { result = super.getTrait().(PathTypeRepr).getPath() }
720736

721-
TypeItemNode resolveSelfTy() { result = resolvePath(this.getSelfPath()) }
737+
TypeItemNode resolveSelfTyBuiltin() { result = resolveBuiltin(this.(Impl).getSelfTy()) }
738+
739+
TypeItemNode resolveSelfTy() {
740+
result = resolvePath(this.getSelfPath())
741+
or
742+
result = this.resolveSelfTyBuiltin()
743+
}
722744

723745
TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) }
724746

@@ -893,7 +915,11 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
893915
}
894916

895917
private class ImplItemNodeImpl extends ImplItemNode {
896-
TypeItemNode resolveSelfTyCand() { result = resolvePathCand(this.getSelfPath()) }
918+
TypeItemNode resolveSelfTyCand() {
919+
result = resolvePathCand(this.getSelfPath())
920+
or
921+
result = this.resolveSelfTyBuiltin()
922+
}
897923

898924
TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
899925
}
@@ -1764,6 +1790,10 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
17641790
or
17651791
result = resolveUseTreeListItem(_, _, path, _) and
17661792
ns = result.getNamespace()
1793+
or
1794+
result = resolveBuiltin(path.getSegment().getTypeRepr()) and
1795+
not path.getSegment().hasTraitTypeRepr() and
1796+
ns.isType()
17671797
}
17681798

17691799
pragma[nomagic]
@@ -2141,7 +2171,9 @@ pragma[nomagic]
21412171
private predicate builtin(string name, ItemNode i) {
21422172
exists(BuiltinSourceFile builtins |
21432173
builtins.getFile().getBaseName() = "types.rs" and
2144-
i = builtins.getASuccessor(name)
2174+
i = builtins.getASuccessor(name) and
2175+
not name = ["Slice", "Array", "Ref", "Ptr"] and
2176+
not name.matches("Tuple%")
21452177
)
21462178
}
21472179

0 commit comments

Comments
 (0)