Skip to content

Commit f922c42

Browse files
committed
raw
1 parent d1f2d04 commit f922c42

3 files changed

Lines changed: 42 additions & 31 deletions

File tree

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

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,12 @@ private module Input3 implements InputSig3 {
10201020
}
10211021

10221022
predicate inferStep(AstNode n1, TypePath path1, AstNode n2, TypePath path2) {
1023+
// When `n2` is `*n1` propagate type information from a raw pointer type
1024+
// parameter at `n1` (all other deref expressions are handled as calls)
1025+
n1 = n2.(DerefExpr).getExpr() and
1026+
path1 = TypePath::singleton(getPtrTypeParameter()) and
1027+
path2.isEmpty()
1028+
or
10231029
path1.isEmpty() and
10241030
(
10251031
n1 = n2.(ArrayListExpr).getAnExpr() and
@@ -1110,8 +1116,6 @@ private module Input3 implements InputSig3 {
11101116
or
11111117
result = inferAwaitExprType(n, path)
11121118
or
1113-
result = inferDereferencedExprPtrType(n, path)
1114-
or
11151119
result = inferForLoopExprType(n, path)
11161120
or
11171121
result = inferArgList(n, path)
@@ -3108,30 +3112,6 @@ private Type inferArrayExprType(ArrayExpr ae) { exists(ae) and result instanceof
31083112
pragma[nomagic]
31093113
private Type inferRangeExprType(RangeExpr re) { result = TDataType(getRangeType(re)) }
31103114

3111-
pragma[nomagic]
3112-
private Type getInferredDerefType(DerefExpr de, TypePath path) { result = inferType(de, path) }
3113-
3114-
pragma[nomagic]
3115-
private PtrType getInferredDerefExprPtrType(DerefExpr de) { result = inferType(de.getExpr()) }
3116-
3117-
/**
3118-
* Gets the inferred type of `n` at `path` when `n` occurs in a dereference
3119-
* expression `*n` and when `n` is known to have a raw pointer type.
3120-
*/
3121-
private Type inferDereferencedExprPtrType(AstNode n, TypePath path) {
3122-
exists(DerefExpr de, PtrType type, TypePath suffix |
3123-
de.getExpr() = n and
3124-
type = getInferredDerefExprPtrType(de) and
3125-
result = getInferredDerefType(de, suffix) and
3126-
path = TypePath::cons(type.getPositionalTypeParameter(0), suffix)
3127-
)
3128-
or
3129-
exists(TypePath path0 |
3130-
result = inferType(n.(DerefExpr).getExpr(), path0) and
3131-
path0.isCons(getPtrTypeParameter(), path)
3132-
)
3133-
}
3134-
31353115
/**
31363116
* A matching configuration for resolving types of deconstruction patterns like
31373117
* `let Foo { bar } = ...` or `let Some(x) = ...`.

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,18 +2778,42 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
27782778
private Type inferTypeContextualCand(AstNode n, TypePath prefix, TypePath path) {
27792779
result = inferTypeContextualCand(n, path) and
27802780
hasUnknownType(n) and
2781-
prefix = path.getAPrefix()
2781+
prefix = path.getAPrefix() and
2782+
// no need to propagate `UnknownType`s contextually; `n` must already have an
2783+
// `UnknownType` at some prefix of `path`
2784+
not result instanceof UnknownType
2785+
}
2786+
2787+
pragma[nomagic]
2788+
private Type inferTypeContextual0(AstNode n, TypePath path) {
2789+
exists(TypePath prefix |
2790+
result = inferTypeContextualCand(n, prefix, path) and
2791+
hasUnknownTypeAt(n, prefix)
2792+
)
2793+
}
2794+
2795+
pragma[nomagic]
2796+
private predicate isValidContextualNonEmptyPath(AstNode n, TypePath path) {
2797+
hasUnknownType(n) and
2798+
exists(TypePath prefix, TypeParameter tp |
2799+
tp = inferType(n, prefix).getATypeParameter() and
2800+
path = TypePath::snoc(prefix, tp)
2801+
)
27822802
}
27832803

27842804
/**
27852805
* Gets the contextually inferred type of `n` at `path`, if any. This is only
2786-
* allowed when `n` has `UnknownType` at some prefix of `path`.
2806+
* allowed when `n` has `UnknownType` at some prefix of `path`, and furthermore
2807+
* if `path` is non-empty, then it must be compatible with an already inferred
2808+
* type (contextually or not).
27872809
*/
27882810
pragma[nomagic]
27892811
Type inferTypeContextual(AstNode n, TypePath path) {
2790-
exists(TypePath prefix |
2791-
result = inferTypeContextualCand(n, prefix, path) and
2792-
hasUnknownTypeAt(n, prefix)
2812+
result = inferTypeContextual0(n, path) and
2813+
(
2814+
path.isEmpty()
2815+
or
2816+
isValidContextualNonEmptyPath(n, path)
27932817
)
27942818
}
27952819
}

shared/util/codeql/util/UnboundList.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,12 @@ module Make<LocationSig Location, InputSig<Location> Input> {
191191
*/
192192
bindingset[suffix]
193193
UnboundList cons(Element e, UnboundList suffix) { result = singleton(e).append(suffix) }
194+
195+
/**
196+
* Gets the list obtained by appending the singleton list `e`
197+
* after `prefix`.
198+
*/
199+
bindingset[prefix]
200+
UnboundList snoc(UnboundList prefix, Element e) { result = prefix.append(singleton(e)) }
194201
}
195202
}

0 commit comments

Comments
 (0)