C++: Move Expr location workaround to Expr.qll

This workaround from `DataFlowUtil.qll` should be useful for any query
that selects an `Expr`. In particular, it's useful for IR data flow.

This commit does not include test changes.
This commit is contained in:
Jonas Jensen
2020-04-06 14:08:19 +02:00
parent 1096e5d947
commit bf7614a4c9
2 changed files with 27 additions and 23 deletions

View File

@@ -114,33 +114,12 @@ class ExprNode extends Node, TExprNode {
override string toString() { result = expr.toString() } override string toString() { result = expr.toString() }
override Location getLocation() { override Location getLocation() { result = expr.getLocation() }
result = getExprLocationOverride(expr)
or
not exists(getExprLocationOverride(expr)) and
result = expr.getLocation()
}
/** Gets the expression corresponding to this node. */ /** Gets the expression corresponding to this node. */
Expr getExpr() { result = expr } Expr getExpr() { result = expr }
} }
/**
* Gets a location for `e` that's more accurate than `e.getLocation()`, if any.
*/
private Location getExprLocationOverride(Expr e) {
// Base case: the parent has a better location than `e`.
e.getLocation() instanceof UnknownExprLocation and
result = e.getParent().getLocation() and
not result instanceof UnknownLocation
or
// Recursive case: the parent has a location override that's better than what
// `e` has.
e.getLocation() instanceof UnknownExprLocation and
result = getExprLocationOverride(e.getParent()) and
not result instanceof UnknownLocation
}
abstract class ParameterNode extends Node, TNode { abstract class ParameterNode extends Node, TNode {
/** /**
* Holds if this node is the parameter of `c` at the specified (zero-based) * Holds if this node is the parameter of `c` at the specified (zero-based)

View File

@@ -53,7 +53,32 @@ class Expr extends StmtParent, @expr {
Element getParent() { exprparents(underlyingElement(this), _, unresolveElement(result)) } Element getParent() { exprparents(underlyingElement(this), _, unresolveElement(result)) }
/** Gets the location of this expression. */ /** Gets the location of this expression. */
override Location getLocation() { exprs(underlyingElement(this), _, result) } override Location getLocation() {
result = this.getExprLocationOverride()
or
not exists(this.getExprLocationOverride()) and
result = this.getDbLocation()
}
/**
* Gets a location for this expression that's more accurate than
* `getDbLocation()`, if any.
*/
private Location getExprLocationOverride() {
// Base case: the parent has a better location than `this`.
this.getDbLocation() instanceof UnknownExprLocation and
result = this.getParent().(Expr).getDbLocation() and
not result instanceof UnknownLocation
or
// Recursive case: the parent has a location override that's better than
// what `this` has.
this.getDbLocation() instanceof UnknownExprLocation and
result = this.getParent().(Expr).getExprLocationOverride() and
not result instanceof UnknownLocation
}
/** Gets the location of this expressions, raw from the database. */
private Location getDbLocation() { exprs(underlyingElement(this), _, result) }
/** Holds if this is an auxiliary expression generated by the compiler. */ /** Holds if this is an auxiliary expression generated by the compiler. */
predicate isCompilerGenerated() { predicate isCompilerGenerated() {