Skip to content

Commit 6748f38

Browse files
committed
C++: Add test demonstrating differences between AST and IR field flow. Also refactored the partial definitions test
1 parent abd05bc commit 6748f38

File tree

4 files changed

+137
-32
lines changed

4 files changed

+137
-32
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
private import semmle.code.cpp.ir.dataflow.DataFlow as IR
2+
private import semmle.code.cpp.dataflow.DataFlow as AST
3+
private import cpp
4+
5+
private newtype TNode =
6+
TASTNode(AST::DataFlow::Node n) or
7+
TIRNode(IR::DataFlow::Node n)
8+
9+
class Node extends TNode {
10+
string toString() { none() }
11+
12+
IR::DataFlow::Node asIR() { none() }
13+
14+
AST::DataFlow::Node asAST() { none() }
15+
16+
Location getLocation() { none() }
17+
}
18+
19+
class ASTNode extends Node, TASTNode {
20+
AST::DataFlow::Node n;
21+
22+
ASTNode() { this = TASTNode(n) }
23+
24+
override string toString() { result = n.toString() }
25+
26+
override AST::DataFlow::Node asAST() { result = n }
27+
28+
override Location getLocation() { result = n.getLocation() }
29+
}
30+
31+
class IRNode extends Node, TIRNode {
32+
IR::DataFlow::Node n;
33+
34+
IRNode() { this = TIRNode(n) }
35+
36+
override string toString() { result = n.toString() }
37+
38+
override IR::DataFlow::Node asIR() { result = n }
39+
40+
override Location getLocation() { result = n.getLocation() }
41+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... | AST only |
2+
| A.cpp:47:12:47:18 | new | A.cpp:49:13:49:13 | c | AST only |
3+
| A.cpp:55:12:55:19 | new | A.cpp:56:13:56:15 | call to get | AST only |
4+
| A.cpp:57:17:57:23 | new | A.cpp:57:28:57:30 | call to get | AST only |
5+
| A.cpp:64:21:64:28 | new | A.cpp:66:14:66:14 | c | AST only |
6+
| A.cpp:73:25:73:32 | new | A.cpp:75:14:75:14 | c | AST only |
7+
| A.cpp:98:12:98:18 | new | A.cpp:120:16:120:16 | a | AST only |
8+
| A.cpp:126:12:126:18 | new | A.cpp:132:13:132:13 | c | AST only |
9+
| A.cpp:142:14:142:20 | new | A.cpp:153:16:153:16 | c | AST only |
10+
| A.cpp:143:25:143:31 | new | A.cpp:152:13:152:13 | b | AST only |
11+
| A.cpp:150:12:150:18 | new | A.cpp:152:13:152:13 | b | AST only |
12+
| A.cpp:159:12:159:18 | new | A.cpp:165:26:165:29 | head | AST only |
13+
| A.cpp:159:12:159:18 | new | A.cpp:169:15:169:18 | head | AST only |
14+
| B.cpp:6:15:6:24 | new | B.cpp:9:20:9:24 | elem1 | AST only |
15+
| B.cpp:15:15:15:27 | new | B.cpp:19:20:19:24 | elem2 | AST only |
16+
| C.cpp:22:12:22:21 | new | C.cpp:29:10:29:11 | s1 | AST only |
17+
| C.cpp:24:16:24:25 | new | C.cpp:31:10:31:11 | s3 | AST only |
18+
| D.cpp:28:15:28:24 | new | D.cpp:22:25:22:31 | call to getElem | AST only |
19+
| D.cpp:35:15:35:24 | new | D.cpp:22:25:22:31 | call to getElem | AST only |
20+
| D.cpp:42:15:42:24 | new | D.cpp:22:25:22:31 | call to getElem | AST only |
21+
| D.cpp:49:15:49:24 | new | D.cpp:22:25:22:31 | call to getElem | AST only |
22+
| D.cpp:56:15:56:24 | new | D.cpp:64:25:64:28 | elem | AST only |
23+
| E.cpp:28:21:28:23 | ref arg raw | E.cpp:31:10:31:12 | raw | AST only |
24+
| E.cpp:29:24:29:29 | ref arg buffer | E.cpp:32:13:32:18 | buffer | AST only |
25+
| E.cpp:30:28:30:33 | ref arg buffer | E.cpp:21:18:21:23 | buffer | AST only |
26+
| aliasing.cpp:37:13:37:22 | call to user_input | aliasing.cpp:38:11:38:12 | m1 | IR only |
27+
| aliasing.cpp:42:11:42:20 | call to user_input | aliasing.cpp:43:13:43:14 | m1 | IR only |
28+
| aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 | IR only |
29+
| aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 | IR only |
30+
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:51:10:51:20 | call to getDirectly | AST only |
31+
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:57:10:57:22 | call to getIndirectly | AST only |
32+
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | AST only |
33+
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:111:25:111:25 | a | AST only |
34+
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:115:27:115:27 | a | AST only |
35+
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | AST only |
36+
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | AST only |
37+
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | AST only |
38+
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | AST only |
39+
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
40+
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
41+
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
42+
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
43+
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
44+
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
45+
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
46+
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
47+
| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | AST only |
48+
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | AST only |
49+
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | AST only |
50+
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:29:12:29:12 | call to b | AST only |
51+
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:23:23:23:23 | a | AST only |
52+
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:28:23:28:23 | a | AST only |
53+
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:33:23:33:23 | a | AST only |
54+
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | AST only |
55+
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | AST only |
56+
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | AST only |
57+
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | AST only |
58+
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | AST only |
59+
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | AST only |
60+
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | AST only |
61+
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:33:25:33:25 | a | AST only |
62+
| struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | AST only |
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @kind problem
3+
*/
4+
5+
import cpp
6+
import Nodes
7+
import IRConfiguration as IRConf
8+
import ASTConfiguration as ASTConf
9+
private import semmle.code.cpp.ir.dataflow.DataFlow as IR
10+
private import semmle.code.cpp.dataflow.DataFlow as AST
11+
12+
from Node source, Node sink, IRConf::Conf irConf, ASTConf::Conf astConf, string msg
13+
where
14+
irConf.hasFlow(source.asIR(), sink.asIR()) and
15+
not exists(AST::DataFlow::Node astSource, AST::DataFlow::Node astSink |
16+
astSource.asExpr() = source.asIR().asExpr() and
17+
astSink.asExpr() = sink.asIR().asExpr()
18+
|
19+
astConf.hasFlow(astSource, astSink)
20+
) and
21+
msg = "IR only"
22+
or
23+
astConf.hasFlow(source.asAST(), sink.asAST()) and
24+
not exists(IR::DataFlow::Node irSource, IR::DataFlow::Node irSink |
25+
irSource.asExpr() = source.asAST().asExpr() and
26+
irSink.asExpr() = sink.asAST().asExpr()
27+
|
28+
irConf.hasFlow(irSource, irSink)
29+
) and
30+
msg = "AST only"
31+
select source, sink, msg

cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,14 @@
55
import cpp
66
import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IR
77
import semmle.code.cpp.dataflow.DataFlow::DataFlow as AST
8+
import Nodes
89

9-
newtype TNode =
10-
TASTNode(AST::Node n) or
11-
TIRNode(IR::Node n)
12-
13-
class Node extends TNode {
14-
string toString() { none() }
15-
16-
IR::Node asIR() { none() }
17-
18-
AST::Node asAST() { none() }
19-
20-
Location getLocation() { none() }
21-
}
22-
23-
class ASTNode extends Node, TASTNode {
24-
AST::Node n;
25-
26-
ASTNode() { this = TASTNode(n) }
27-
10+
class ASTPartialDefNode extends ASTNode {
2811
override string toString() { result = n.asPartialDefinition().toString() }
29-
30-
override AST::Node asAST() { result = n }
31-
32-
override Location getLocation() { result = n.getLocation() }
3312
}
3413

35-
class IRNode extends Node, TIRNode {
36-
IR::Node n;
37-
38-
IRNode() { this = TIRNode(n) }
39-
14+
class IRPartialDefNode extends IRNode {
4015
override string toString() { result = n.asPartialDefinition().toString() }
41-
42-
override IR::Node asIR() { result = n }
43-
44-
override Location getLocation() { result = n.getLocation() }
4516
}
4617

4718
from Node node, AST::Node astNode, IR::Node irNode, string msg

0 commit comments

Comments
 (0)