Skip to content

Commit 22b1503

Browse files
committed
C++: Split DataFlow::Node.asExpr into two
The existing `Node.asExpr` predicate changes semantics so it becomes the one that most users should use when they don't want to think about `Conversion`s. A new `Node.asConvertedExpr` predicate is added and has the same semantics as the old `Node.asExpr` predicate. It's for advanced users that know about `Conversion`s and want to account for them.
1 parent dcb24e0 commit 22b1503

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,22 @@ class Node extends Instruction {
2424
result = this.getResultType()
2525
}
2626

27-
/** Gets the expression corresponding to this node, if any. */
28-
Expr asExpr() { result = this.getConvertedResultExpression() }
27+
/**
28+
* Gets the non-conversion expression corresponding to this node, if any. If
29+
* this node strictly (in the sense of `asConvertedExpr`) corresponds to a
30+
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
31+
* expression.
32+
*/
33+
Expr asExpr() {
34+
result.getConversion*() = this.getConvertedResultExpression() and
35+
not result instanceof Conversion
36+
}
37+
38+
/**
39+
* Gets the expression corresponding to this node, if any. The returned
40+
* expression may be a `Conversion`.
41+
*/
42+
Expr asConvertedExpr() { result = this.getConvertedResultExpression() }
2943

3044
/** Gets the parameter corresponding to this node, if any. */
3145
Parameter asParameter() { result = this.(InitializeParameterInstruction).getParameter() }
@@ -48,10 +62,21 @@ class Node extends Instruction {
4862
* An expression, viewed as a node in a data flow graph.
4963
*/
5064
class ExprNode extends Node {
51-
Expr expr;
65+
ExprNode() { exists(this.asExpr()) }
66+
67+
/**
68+
* Gets the non-conversion expression corresponding to this node, if any. If
69+
* this node strictly (in the sense of `getConvertedExpr`) corresponds to a
70+
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
71+
* expression.
72+
*/
73+
Expr getExpr() { result = this.asExpr() }
5274

53-
ExprNode() { expr = this.asExpr() }
54-
Expr getExpr() { result = expr }
75+
/**
76+
* Gets the expression corresponding to this node, if any. The returned
77+
* expression may be a `Conversion`.
78+
*/
79+
Expr getConvertedExpr() { result = this.asConvertedExpr() }
5580
}
5681

5782
/**
@@ -98,10 +123,17 @@ abstract class PostUpdateNode extends Node {
98123
}
99124

100125
/**
101-
* Gets the `Node` corresponding to `e`.
126+
* Gets a `Node` corresponding to `e` or any of its conversions. There is no
127+
* result if `e` is a `Conversion`.
102128
*/
103129
ExprNode exprNode(Expr e) { result.getExpr() = e }
104130

131+
/**
132+
* Gets the `Node` corresponding to `e`, if any. Here, `e` may be a
133+
* `Conversion`.
134+
*/
135+
ExprNode convertedExprNode(Expr e) { result.getExpr() = e }
136+
105137
/**
106138
* Gets the `Node` corresponding to the value of `p` at function entry.
107139
*/

0 commit comments

Comments
 (0)