-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathNestedFields.qll
More file actions
69 lines (63 loc) · 1.51 KB
/
NestedFields.qll
File metadata and controls
69 lines (63 loc) · 1.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* Provides a class for reasoning about nested field accesses, for example
* the access `myLine.start.x`.
*/
import cpp
/**
* Gets a `Field` that is within the given `Struct`, either directly or nested
* inside one or more levels of member structs.
*/
private Field getANestedField(Struct s) {
result = s.getAField()
or
exists(NestedStruct ns |
s = ns.getDeclaringType() and
result = getANestedField(ns)
)
}
/**
* Unwraps a series of field accesses to determine the outer-most qualifier.
*/
private Expr getUltimateQualifier(FieldAccess fa) {
exists(Expr qualifier | qualifier = fa.getQualifier() |
result = getUltimateQualifier(qualifier)
or
not qualifier instanceof FieldAccess and result = qualifier
)
}
/**
* A nested field access, for example the access `myLine.start.x`.
*/
class NestedFieldAccess extends FieldAccess {
Expr ultimateQualifier;
NestedFieldAccess() {
ultimateQualifier = getUltimateQualifier(this) and
this.getTarget() = getANestedField(ultimateQualifier.getType().stripType())
}
/**
* Gets the outermost qualifier of this nested field access. In the
* following example, the access to `myLine.start.x` has outermost qualifier
* `myLine`:
* ```
* struct Point
* {
* float x, y;
* };
*
* struct Line
* {
* Point start, end;
* };
*
* void init()
* {
* Line myLine;
*
* myLine.start.x = 0.0f;
*
* // ...
* }
* ```
*/
Expr getUltimateQualifier() { result = ultimateQualifier }
}