Skip to content

Commit 5382a02

Browse files
committed
Rust: Add more flow tests
1 parent 02e18ae commit 5382a02

File tree

2 files changed

+189
-63
lines changed

2 files changed

+189
-63
lines changed

rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected

Lines changed: 108 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -75,42 +75,113 @@
7575
| main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} |
7676
| main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 |
7777
| main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 |
78-
| main.rs:104:14:104:28 | Some(...) | main.rs:104:9:104:10 | s1 |
78+
| main.rs:104:14:104:37 | ...::Some(...) | main.rs:104:9:104:10 | s1 |
7979
| main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 |
8080
| main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 |
81-
| main.rs:105:14:105:20 | Some(...) | main.rs:105:9:105:10 | s2 |
82-
| main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n |
83-
| main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n |
84-
| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
85-
| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
86-
| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:27:114:1 | { ... } |
87-
| main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n |
88-
| main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n |
89-
| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
90-
| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
91-
| main.rs:117:9:117:9 | [SSA] a | main.rs:118:5:118:5 | a |
92-
| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | [SSA] a |
93-
| main.rs:117:13:117:17 | { ... } | main.rs:117:9:117:9 | a |
94-
| main.rs:117:15:117:15 | 0 | main.rs:117:13:117:17 | { ... } |
95-
| main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | { ... } |
96-
| main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b |
97-
| main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b |
98-
| main.rs:121:22:121:28 | ...: bool | main.rs:121:22:121:22 | b |
99-
| main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a |
100-
| main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a |
101-
| main.rs:122:13:127:5 | 'block: { ... } | main.rs:122:9:122:9 | a |
102-
| main.rs:124:13:124:26 | break ''block 1 | main.rs:122:13:127:5 | 'block: { ... } |
103-
| main.rs:124:26:124:26 | 1 | main.rs:124:13:124:26 | break ''block 1 |
104-
| main.rs:126:9:126:9 | 2 | main.rs:122:13:127:5 | 'block: { ... } |
105-
| main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | { ... } |
106-
| main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b |
107-
| main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b |
108-
| main.rs:131:22:131:28 | ...: bool | main.rs:131:22:131:22 | b |
109-
| main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a |
110-
| main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a |
111-
| main.rs:132:13:137:5 | 'block: { ... } | main.rs:132:9:132:9 | a |
112-
| main.rs:134:13:134:26 | break ''block 1 | main.rs:132:13:137:5 | 'block: { ... } |
113-
| main.rs:134:26:134:26 | 1 | main.rs:134:13:134:26 | break ''block 1 |
114-
| main.rs:136:9:136:22 | break ''block 2 | main.rs:132:13:137:5 | 'block: { ... } |
115-
| main.rs:136:22:136:22 | 2 | main.rs:136:9:136:22 | break ''block 2 |
116-
| main.rs:138:5:138:5 | a | main.rs:131:38:139:1 | { ... } |
81+
| main.rs:105:14:105:28 | ...::Some(...) | main.rs:105:9:105:10 | s2 |
82+
| main.rs:107:22:107:22 | [SSA] n | main.rs:107:33:107:33 | n |
83+
| main.rs:107:22:107:22 | n | main.rs:107:22:107:22 | [SSA] n |
84+
| main.rs:107:28:107:34 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
85+
| main.rs:108:25:108:31 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
86+
| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:37:114:1 | { ... } |
87+
| main.rs:111:22:111:22 | [SSA] n | main.rs:111:33:111:33 | n |
88+
| main.rs:111:22:111:22 | n | main.rs:111:22:111:22 | [SSA] n |
89+
| main.rs:111:28:111:34 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
90+
| main.rs:112:25:112:31 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
91+
| main.rs:117:9:117:10 | [SSA] s1 | main.rs:119:11:119:12 | s1 |
92+
| main.rs:117:9:117:10 | s1 | main.rs:117:9:117:10 | [SSA] s1 |
93+
| main.rs:117:14:117:29 | Some(...) | main.rs:117:9:117:10 | s1 |
94+
| main.rs:118:9:118:10 | [SSA] s2 | main.rs:123:11:123:12 | s2 |
95+
| main.rs:118:9:118:10 | s2 | main.rs:118:9:118:10 | [SSA] s2 |
96+
| main.rs:118:14:118:20 | Some(...) | main.rs:118:9:118:10 | s2 |
97+
| main.rs:120:14:120:14 | [SSA] n | main.rs:120:25:120:25 | n |
98+
| main.rs:120:14:120:14 | n | main.rs:120:14:120:14 | [SSA] n |
99+
| main.rs:120:20:120:26 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } |
100+
| main.rs:121:17:121:23 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } |
101+
| main.rs:123:5:126:5 | match s2 { ... } | main.rs:116:39:127:1 | { ... } |
102+
| main.rs:124:14:124:14 | [SSA] n | main.rs:124:25:124:25 | n |
103+
| main.rs:124:14:124:14 | n | main.rs:124:14:124:14 | [SSA] n |
104+
| main.rs:124:20:124:26 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } |
105+
| main.rs:125:17:125:23 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } |
106+
| main.rs:135:9:135:10 | [SSA] s1 | main.rs:137:11:137:12 | s1 |
107+
| main.rs:135:9:135:10 | s1 | main.rs:135:9:135:10 | [SSA] s1 |
108+
| main.rs:135:14:135:34 | ...::A(...) | main.rs:135:9:135:10 | s1 |
109+
| main.rs:136:9:136:10 | [SSA] s2 | main.rs:144:11:144:12 | s2 |
110+
| main.rs:136:9:136:10 | s2 | main.rs:136:9:136:10 | [SSA] s2 |
111+
| main.rs:136:14:136:25 | ...::B(...) | main.rs:136:9:136:10 | s2 |
112+
| main.rs:137:11:137:12 | s1 | main.rs:141:11:141:12 | s1 |
113+
| main.rs:138:19:138:19 | [SSA] n | main.rs:138:30:138:30 | n |
114+
| main.rs:138:19:138:19 | n | main.rs:138:19:138:19 | [SSA] n |
115+
| main.rs:138:25:138:31 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } |
116+
| main.rs:139:19:139:19 | [SSA] n | main.rs:139:30:139:30 | n |
117+
| main.rs:139:19:139:19 | n | main.rs:139:19:139:19 | [SSA] n |
118+
| main.rs:139:25:139:31 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } |
119+
| main.rs:142:10:142:36 | [SSA] [match(true)] phi | main.rs:142:47:142:47 | n |
120+
| main.rs:142:20:142:20 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:36 | [SSA] [match(true)] phi |
121+
| main.rs:142:20:142:20 | [SSA] n | main.rs:142:20:142:20 | [SSA] [input] [match(true)] phi |
122+
| main.rs:142:20:142:20 | n | main.rs:142:20:142:20 | [SSA] n |
123+
| main.rs:142:35:142:35 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:36 | [SSA] [match(true)] phi |
124+
| main.rs:142:35:142:35 | [SSA] n | main.rs:142:35:142:35 | [SSA] [input] [match(true)] phi |
125+
| main.rs:142:35:142:35 | n | main.rs:142:35:142:35 | [SSA] n |
126+
| main.rs:142:42:142:48 | sink(...) | main.rs:141:5:143:5 | match s1 { ... } |
127+
| main.rs:144:5:147:5 | match s2 { ... } | main.rs:134:42:148:1 | { ... } |
128+
| main.rs:145:19:145:19 | [SSA] n | main.rs:145:30:145:30 | n |
129+
| main.rs:145:19:145:19 | n | main.rs:145:19:145:19 | [SSA] n |
130+
| main.rs:145:25:145:31 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } |
131+
| main.rs:146:19:146:19 | [SSA] n | main.rs:146:30:146:30 | n |
132+
| main.rs:146:19:146:19 | n | main.rs:146:19:146:19 | [SSA] n |
133+
| main.rs:146:25:146:31 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } |
134+
| main.rs:153:9:153:10 | [SSA] s1 | main.rs:155:11:155:12 | s1 |
135+
| main.rs:153:9:153:10 | s1 | main.rs:153:9:153:10 | [SSA] s1 |
136+
| main.rs:153:14:153:26 | A(...) | main.rs:153:9:153:10 | s1 |
137+
| main.rs:154:9:154:10 | [SSA] s2 | main.rs:162:11:162:12 | s2 |
138+
| main.rs:154:9:154:10 | s2 | main.rs:154:9:154:10 | [SSA] s2 |
139+
| main.rs:154:14:154:17 | B(...) | main.rs:154:9:154:10 | s2 |
140+
| main.rs:155:11:155:12 | s1 | main.rs:159:11:159:12 | s1 |
141+
| main.rs:156:11:156:11 | [SSA] n | main.rs:156:22:156:22 | n |
142+
| main.rs:156:11:156:11 | n | main.rs:156:11:156:11 | [SSA] n |
143+
| main.rs:156:17:156:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } |
144+
| main.rs:157:11:157:11 | [SSA] n | main.rs:157:22:157:22 | n |
145+
| main.rs:157:11:157:11 | n | main.rs:157:11:157:11 | [SSA] n |
146+
| main.rs:157:17:157:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } |
147+
| main.rs:160:10:160:20 | [SSA] [match(true)] phi | main.rs:160:31:160:31 | n |
148+
| main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi |
149+
| main.rs:160:12:160:12 | [SSA] n | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi |
150+
| main.rs:160:12:160:12 | n | main.rs:160:12:160:12 | [SSA] n |
151+
| main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi |
152+
| main.rs:160:19:160:19 | [SSA] n | main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi |
153+
| main.rs:160:19:160:19 | n | main.rs:160:19:160:19 | [SSA] n |
154+
| main.rs:160:26:160:32 | sink(...) | main.rs:159:5:161:5 | match s1 { ... } |
155+
| main.rs:162:5:165:5 | match s2 { ... } | main.rs:152:44:166:1 | { ... } |
156+
| main.rs:163:11:163:11 | [SSA] n | main.rs:163:22:163:22 | n |
157+
| main.rs:163:11:163:11 | n | main.rs:163:11:163:11 | [SSA] n |
158+
| main.rs:163:17:163:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } |
159+
| main.rs:164:11:164:11 | [SSA] n | main.rs:164:22:164:22 | n |
160+
| main.rs:164:11:164:11 | n | main.rs:164:11:164:11 | [SSA] n |
161+
| main.rs:164:17:164:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } |
162+
| main.rs:169:9:169:9 | [SSA] a | main.rs:170:5:170:5 | a |
163+
| main.rs:169:9:169:9 | a | main.rs:169:9:169:9 | [SSA] a |
164+
| main.rs:169:13:169:17 | { ... } | main.rs:169:9:169:9 | a |
165+
| main.rs:169:15:169:15 | 0 | main.rs:169:13:169:17 | { ... } |
166+
| main.rs:170:5:170:5 | a | main.rs:168:31:171:1 | { ... } |
167+
| main.rs:173:22:173:22 | [SSA] b | main.rs:175:12:175:12 | b |
168+
| main.rs:173:22:173:22 | b | main.rs:173:22:173:22 | [SSA] b |
169+
| main.rs:173:22:173:28 | ...: bool | main.rs:173:22:173:22 | b |
170+
| main.rs:174:9:174:9 | [SSA] a | main.rs:180:5:180:5 | a |
171+
| main.rs:174:9:174:9 | a | main.rs:174:9:174:9 | [SSA] a |
172+
| main.rs:174:13:179:5 | 'block: { ... } | main.rs:174:9:174:9 | a |
173+
| main.rs:176:13:176:26 | break ''block 1 | main.rs:174:13:179:5 | 'block: { ... } |
174+
| main.rs:176:26:176:26 | 1 | main.rs:176:13:176:26 | break ''block 1 |
175+
| main.rs:178:9:178:9 | 2 | main.rs:174:13:179:5 | 'block: { ... } |
176+
| main.rs:180:5:180:5 | a | main.rs:173:38:181:1 | { ... } |
177+
| main.rs:183:22:183:22 | [SSA] b | main.rs:185:12:185:12 | b |
178+
| main.rs:183:22:183:22 | b | main.rs:183:22:183:22 | [SSA] b |
179+
| main.rs:183:22:183:28 | ...: bool | main.rs:183:22:183:22 | b |
180+
| main.rs:184:9:184:9 | [SSA] a | main.rs:190:5:190:5 | a |
181+
| main.rs:184:9:184:9 | a | main.rs:184:9:184:9 | [SSA] a |
182+
| main.rs:184:13:189:5 | 'block: { ... } | main.rs:184:9:184:9 | a |
183+
| main.rs:186:13:186:26 | break ''block 1 | main.rs:184:13:189:5 | 'block: { ... } |
184+
| main.rs:186:26:186:26 | 1 | main.rs:186:13:186:26 | break ''block 1 |
185+
| main.rs:188:9:188:22 | break ''block 2 | main.rs:184:13:189:5 | 'block: { ... } |
186+
| main.rs:188:22:188:22 | 2 | main.rs:188:9:188:22 | break ''block 2 |
187+
| main.rs:190:5:190:5 | a | main.rs:183:38:191:1 | { ... } |

rust/ql/test/library-tests/dataflow/local/main.rs

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,24 @@ fn direct() {
1616
}
1717

1818
fn variable_usage() {
19-
let s = source(1);
20-
sink(s); // $ hasValueFlow=1
19+
let s = source(2);
20+
sink(s); // $ hasValueFlow=2
2121
}
2222

2323
fn if_expression(cond: bool) {
24-
let a = source(1);
24+
let a = source(3);
2525
let b = 2;
2626
let c = if cond { a } else { b };
27-
sink(c); // $ hasValueFlow=1
27+
sink(c); // $ hasValueFlow=3
2828
}
2929

3030
fn match_expression(m: Option<i64>) {
31-
let a = source(1);
31+
let a = source(4);
3232
let b = match m {
3333
Some(_) => a,
3434
None => 0,
3535
};
36-
sink(b); // $ hasValueFlow=1
36+
sink(b); // $ hasValueFlow=4
3737
}
3838

3939
fn loop_with_break() {
@@ -42,29 +42,29 @@ fn loop_with_break() {
4242
};
4343
sink(a);
4444
let b = loop {
45-
break source(1);
45+
break source(5);
4646
};
47-
sink(b); // $ hasValueFlow=1
47+
sink(b); // $ hasValueFlow=5
4848
}
4949

5050
fn assignment() {
5151
let mut i = 1;
5252
sink(i);
53-
i = source(2);
54-
sink(i); // $ hasValueFlow=2
53+
i = source(6);
54+
sink(i); // $ hasValueFlow=6
5555
}
5656

5757
// -----------------------------------------------------------------------------
5858
// Data flow through data structures by writing and reading
5959

6060
fn box_deref() {
61-
let i = Box::new(source(1));
62-
sink(*i); // $ MISSING: hasValueFlow=1
61+
let i = Box::new(source(7));
62+
sink(*i); // $ MISSING: hasValueFlow=7
6363
}
6464

6565
fn tuple() {
66-
let a = (source(1), 2);
67-
sink(a.0); // $ MISSING: hasValueFlow=1
66+
let a = (source(8), 2);
67+
sink(a.0); // $ MISSING: hasValueFlow=8
6868
sink(a.1);
6969
}
7070

@@ -76,35 +76,48 @@ struct Point {
7676

7777
fn struct_field() {
7878
let p = Point {
79-
x: source(1),
79+
x: source(9),
8080
y: 2,
81-
z: source(3),
81+
z: source(10),
8282
};
83-
sink(p.x); // MISSING: hasValueFlow=1
83+
sink(p.x); // $ MISSING: hasValueFlow=9
8484
sink(p.y);
85-
sink(p.z); // MISSING: hasValueFlow=3
85+
sink(p.z); // $ MISSING: hasValueFlow=10
8686
}
8787

8888
// -----------------------------------------------------------------------------
8989
// Data flow through data structures by pattern matching
9090

9191
fn struct_pattern_match() {
9292
let p = Point {
93-
x: source(1),
93+
x: source(11),
9494
y: 2,
95-
z: source(3),
95+
z: source(12),
9696
};
9797
let Point { x: a, y: b, z: c } = p;
98-
sink(a); // MISSING: hasValueFlow=1
98+
sink(a); // $ MISSING: hasValueFlow=11
9999
sink(b);
100-
sink(c); // MISSING: hasValueFlow=3
100+
sink(c); // $ MISSING: hasValueFlow=12
101101
}
102102

103-
fn option_pattern_match() {
104-
let s1 = Some(source(1));
103+
fn option_pattern_match_qualified() {
104+
let s1 = Option::Some(source(13));
105+
let s2 = Option::Some(2);
106+
match s1 {
107+
Option::Some(n) => sink(n), // $ MISSING: hasValueFlow=13
108+
Option::None => sink(0),
109+
}
110+
match s2 {
111+
Option::Some(n) => sink(n),
112+
Option::None => sink(0),
113+
}
114+
}
115+
116+
fn option_pattern_match_unqualified() {
117+
let s1 = Some(source(14));
105118
let s2 = Some(2);
106119
match s1 {
107-
Some(n) => sink(n), // MISSING: hasValueFlow=3
120+
Some(n) => sink(n), // $ MISSING: hasValueFlow=14
108121
None => sink(0),
109122
}
110123
match s2 {
@@ -113,6 +126,45 @@ fn option_pattern_match() {
113126
}
114127
}
115128

129+
enum MyEnum {
130+
A(i64),
131+
B(i64),
132+
}
133+
134+
fn custom_enum_pattern_match_qualified() {
135+
let s1 = MyEnum::A(source(15));
136+
let s2 = MyEnum::B(2);
137+
match s1 {
138+
MyEnum::A(n) => sink(n), // $ MISSING: hasValueFlow=15
139+
MyEnum::B(n) => sink(n),
140+
}
141+
match s1 {
142+
(MyEnum::A(n) | MyEnum::B(n)) => sink(n), // $ MISSING: hasValueFlow=15
143+
}
144+
match s2 {
145+
MyEnum::A(n) => sink(n),
146+
MyEnum::B(n) => sink(n),
147+
}
148+
}
149+
150+
use crate::MyEnum::*;
151+
152+
fn custom_enum_pattern_match_unqualified() {
153+
let s1 = A(source(16));
154+
let s2 = B(2);
155+
match s1 {
156+
A(n) => sink(n), // $ MISSING: hasValueFlow=16
157+
B(n) => sink(n),
158+
}
159+
match s1 {
160+
(A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16
161+
}
162+
match s2 {
163+
A(n) => sink(n),
164+
B(n) => sink(n),
165+
}
166+
}
167+
116168
fn block_expression1() -> i64 {
117169
let a = { 0 };
118170
a
@@ -149,7 +201,10 @@ fn main() {
149201
tuple();
150202
struct_field();
151203
struct_pattern_match();
152-
option_pattern_match();
204+
option_pattern_match_qualified();
205+
option_pattern_match_unqualified();
206+
custom_enum_pattern_match_qualified();
207+
custom_enum_pattern_match_unqualified();
153208
block_expression1();
154209
block_expression2(true);
155210
block_expression3(true);

0 commit comments

Comments
 (0)