Files
codeql/cpp/ql/lib/semmle/code/cpp/NestedFields.qll
Andrew Eisenberg 2c5dd2dfa3 Packaging: Refactor the cpp libraries
This PR separates the core cpp packs into `codeql/cpp-queries` and
`codeql/cpp-all`.

There are very few lines of code changed. Almost all changes are moving
files around.
2021-08-17 11:22:36 -07:00

70 lines
1.5 KiB
Plaintext

/**
* 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
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 }
}