Skip to content

Commit

Permalink
Rust: Add more flow tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Nov 25, 2024
1 parent 02e18ae commit 5382a02
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 63 deletions.
145 changes: 108 additions & 37 deletions rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected
Original file line number Diff line number Diff line change
Expand Up @@ -75,42 +75,113 @@
| main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} |
| main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 |
| main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 |
| main.rs:104:14:104:28 | Some(...) | main.rs:104:9:104:10 | s1 |
| main.rs:104:14:104:37 | ...::Some(...) | main.rs:104:9:104:10 | s1 |
| main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 |
| main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 |
| main.rs:105:14:105:20 | Some(...) | main.rs:105:9:105:10 | s2 |
| main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n |
| main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n |
| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:27:114:1 | { ... } |
| main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n |
| main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n |
| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
| main.rs:117:9:117:9 | [SSA] a | main.rs:118:5:118:5 | a |
| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | [SSA] a |
| main.rs:117:13:117:17 | { ... } | main.rs:117:9:117:9 | a |
| main.rs:117:15:117:15 | 0 | main.rs:117:13:117:17 | { ... } |
| main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | { ... } |
| main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b |
| main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b |
| main.rs:121:22:121:28 | ...: bool | main.rs:121:22:121:22 | b |
| main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a |
| main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a |
| main.rs:122:13:127:5 | 'block: { ... } | main.rs:122:9:122:9 | a |
| main.rs:124:13:124:26 | break ''block 1 | main.rs:122:13:127:5 | 'block: { ... } |
| main.rs:124:26:124:26 | 1 | main.rs:124:13:124:26 | break ''block 1 |
| main.rs:126:9:126:9 | 2 | main.rs:122:13:127:5 | 'block: { ... } |
| main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | { ... } |
| main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b |
| main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b |
| main.rs:131:22:131:28 | ...: bool | main.rs:131:22:131:22 | b |
| main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a |
| main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a |
| main.rs:132:13:137:5 | 'block: { ... } | main.rs:132:9:132:9 | a |
| main.rs:134:13:134:26 | break ''block 1 | main.rs:132:13:137:5 | 'block: { ... } |
| main.rs:134:26:134:26 | 1 | main.rs:134:13:134:26 | break ''block 1 |
| main.rs:136:9:136:22 | break ''block 2 | main.rs:132:13:137:5 | 'block: { ... } |
| main.rs:136:22:136:22 | 2 | main.rs:136:9:136:22 | break ''block 2 |
| main.rs:138:5:138:5 | a | main.rs:131:38:139:1 | { ... } |
| main.rs:105:14:105:28 | ...::Some(...) | main.rs:105:9:105:10 | s2 |
| main.rs:107:22:107:22 | [SSA] n | main.rs:107:33:107:33 | n |
| main.rs:107:22:107:22 | n | main.rs:107:22:107:22 | [SSA] n |
| main.rs:107:28:107:34 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
| main.rs:108:25:108:31 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:37:114:1 | { ... } |
| main.rs:111:22:111:22 | [SSA] n | main.rs:111:33:111:33 | n |
| main.rs:111:22:111:22 | n | main.rs:111:22:111:22 | [SSA] n |
| main.rs:111:28:111:34 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
| main.rs:112:25:112:31 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
| main.rs:117:9:117:10 | [SSA] s1 | main.rs:119:11:119:12 | s1 |
| main.rs:117:9:117:10 | s1 | main.rs:117:9:117:10 | [SSA] s1 |
| main.rs:117:14:117:29 | Some(...) | main.rs:117:9:117:10 | s1 |
| main.rs:118:9:118:10 | [SSA] s2 | main.rs:123:11:123:12 | s2 |
| main.rs:118:9:118:10 | s2 | main.rs:118:9:118:10 | [SSA] s2 |
| main.rs:118:14:118:20 | Some(...) | main.rs:118:9:118:10 | s2 |
| main.rs:120:14:120:14 | [SSA] n | main.rs:120:25:120:25 | n |
| main.rs:120:14:120:14 | n | main.rs:120:14:120:14 | [SSA] n |
| main.rs:120:20:120:26 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } |
| main.rs:121:17:121:23 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } |
| main.rs:123:5:126:5 | match s2 { ... } | main.rs:116:39:127:1 | { ... } |
| main.rs:124:14:124:14 | [SSA] n | main.rs:124:25:124:25 | n |
| main.rs:124:14:124:14 | n | main.rs:124:14:124:14 | [SSA] n |
| main.rs:124:20:124:26 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } |
| main.rs:125:17:125:23 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } |
| main.rs:135:9:135:10 | [SSA] s1 | main.rs:137:11:137:12 | s1 |
| main.rs:135:9:135:10 | s1 | main.rs:135:9:135:10 | [SSA] s1 |
| main.rs:135:14:135:34 | ...::A(...) | main.rs:135:9:135:10 | s1 |
| main.rs:136:9:136:10 | [SSA] s2 | main.rs:144:11:144:12 | s2 |
| main.rs:136:9:136:10 | s2 | main.rs:136:9:136:10 | [SSA] s2 |
| main.rs:136:14:136:25 | ...::B(...) | main.rs:136:9:136:10 | s2 |
| main.rs:137:11:137:12 | s1 | main.rs:141:11:141:12 | s1 |
| main.rs:138:19:138:19 | [SSA] n | main.rs:138:30:138:30 | n |
| main.rs:138:19:138:19 | n | main.rs:138:19:138:19 | [SSA] n |
| main.rs:138:25:138:31 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } |
| main.rs:139:19:139:19 | [SSA] n | main.rs:139:30:139:30 | n |
| main.rs:139:19:139:19 | n | main.rs:139:19:139:19 | [SSA] n |
| main.rs:139:25:139:31 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } |
| main.rs:142:10:142:36 | [SSA] [match(true)] phi | main.rs:142:47:142:47 | n |
| main.rs:142:20:142:20 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:36 | [SSA] [match(true)] phi |
| main.rs:142:20:142:20 | [SSA] n | main.rs:142:20:142:20 | [SSA] [input] [match(true)] phi |
| main.rs:142:20:142:20 | n | main.rs:142:20:142:20 | [SSA] n |
| main.rs:142:35:142:35 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:36 | [SSA] [match(true)] phi |
| main.rs:142:35:142:35 | [SSA] n | main.rs:142:35:142:35 | [SSA] [input] [match(true)] phi |
| main.rs:142:35:142:35 | n | main.rs:142:35:142:35 | [SSA] n |
| main.rs:142:42:142:48 | sink(...) | main.rs:141:5:143:5 | match s1 { ... } |
| main.rs:144:5:147:5 | match s2 { ... } | main.rs:134:42:148:1 | { ... } |
| main.rs:145:19:145:19 | [SSA] n | main.rs:145:30:145:30 | n |
| main.rs:145:19:145:19 | n | main.rs:145:19:145:19 | [SSA] n |
| main.rs:145:25:145:31 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } |
| main.rs:146:19:146:19 | [SSA] n | main.rs:146:30:146:30 | n |
| main.rs:146:19:146:19 | n | main.rs:146:19:146:19 | [SSA] n |
| main.rs:146:25:146:31 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } |
| main.rs:153:9:153:10 | [SSA] s1 | main.rs:155:11:155:12 | s1 |
| main.rs:153:9:153:10 | s1 | main.rs:153:9:153:10 | [SSA] s1 |
| main.rs:153:14:153:26 | A(...) | main.rs:153:9:153:10 | s1 |
| main.rs:154:9:154:10 | [SSA] s2 | main.rs:162:11:162:12 | s2 |
| main.rs:154:9:154:10 | s2 | main.rs:154:9:154:10 | [SSA] s2 |
| main.rs:154:14:154:17 | B(...) | main.rs:154:9:154:10 | s2 |
| main.rs:155:11:155:12 | s1 | main.rs:159:11:159:12 | s1 |
| main.rs:156:11:156:11 | [SSA] n | main.rs:156:22:156:22 | n |
| main.rs:156:11:156:11 | n | main.rs:156:11:156:11 | [SSA] n |
| main.rs:156:17:156:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } |
| main.rs:157:11:157:11 | [SSA] n | main.rs:157:22:157:22 | n |
| main.rs:157:11:157:11 | n | main.rs:157:11:157:11 | [SSA] n |
| main.rs:157:17:157:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } |
| main.rs:160:10:160:20 | [SSA] [match(true)] phi | main.rs:160:31:160:31 | n |
| main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi |
| main.rs:160:12:160:12 | [SSA] n | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi |
| main.rs:160:12:160:12 | n | main.rs:160:12:160:12 | [SSA] n |
| main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi |
| main.rs:160:19:160:19 | [SSA] n | main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi |
| main.rs:160:19:160:19 | n | main.rs:160:19:160:19 | [SSA] n |
| main.rs:160:26:160:32 | sink(...) | main.rs:159:5:161:5 | match s1 { ... } |
| main.rs:162:5:165:5 | match s2 { ... } | main.rs:152:44:166:1 | { ... } |
| main.rs:163:11:163:11 | [SSA] n | main.rs:163:22:163:22 | n |
| main.rs:163:11:163:11 | n | main.rs:163:11:163:11 | [SSA] n |
| main.rs:163:17:163:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } |
| main.rs:164:11:164:11 | [SSA] n | main.rs:164:22:164:22 | n |
| main.rs:164:11:164:11 | n | main.rs:164:11:164:11 | [SSA] n |
| main.rs:164:17:164:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } |
| main.rs:169:9:169:9 | [SSA] a | main.rs:170:5:170:5 | a |
| main.rs:169:9:169:9 | a | main.rs:169:9:169:9 | [SSA] a |
| main.rs:169:13:169:17 | { ... } | main.rs:169:9:169:9 | a |
| main.rs:169:15:169:15 | 0 | main.rs:169:13:169:17 | { ... } |
| main.rs:170:5:170:5 | a | main.rs:168:31:171:1 | { ... } |
| main.rs:173:22:173:22 | [SSA] b | main.rs:175:12:175:12 | b |
| main.rs:173:22:173:22 | b | main.rs:173:22:173:22 | [SSA] b |
| main.rs:173:22:173:28 | ...: bool | main.rs:173:22:173:22 | b |
| main.rs:174:9:174:9 | [SSA] a | main.rs:180:5:180:5 | a |
| main.rs:174:9:174:9 | a | main.rs:174:9:174:9 | [SSA] a |
| main.rs:174:13:179:5 | 'block: { ... } | main.rs:174:9:174:9 | a |
| main.rs:176:13:176:26 | break ''block 1 | main.rs:174:13:179:5 | 'block: { ... } |
| main.rs:176:26:176:26 | 1 | main.rs:176:13:176:26 | break ''block 1 |
| main.rs:178:9:178:9 | 2 | main.rs:174:13:179:5 | 'block: { ... } |
| main.rs:180:5:180:5 | a | main.rs:173:38:181:1 | { ... } |
| main.rs:183:22:183:22 | [SSA] b | main.rs:185:12:185:12 | b |
| main.rs:183:22:183:22 | b | main.rs:183:22:183:22 | [SSA] b |
| main.rs:183:22:183:28 | ...: bool | main.rs:183:22:183:22 | b |
| main.rs:184:9:184:9 | [SSA] a | main.rs:190:5:190:5 | a |
| main.rs:184:9:184:9 | a | main.rs:184:9:184:9 | [SSA] a |
| main.rs:184:13:189:5 | 'block: { ... } | main.rs:184:9:184:9 | a |
| main.rs:186:13:186:26 | break ''block 1 | main.rs:184:13:189:5 | 'block: { ... } |
| main.rs:186:26:186:26 | 1 | main.rs:186:13:186:26 | break ''block 1 |
| main.rs:188:9:188:22 | break ''block 2 | main.rs:184:13:189:5 | 'block: { ... } |
| main.rs:188:22:188:22 | 2 | main.rs:188:9:188:22 | break ''block 2 |
| main.rs:190:5:190:5 | a | main.rs:183:38:191:1 | { ... } |
107 changes: 81 additions & 26 deletions rust/ql/test/library-tests/dataflow/local/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ fn direct() {
}

fn variable_usage() {
let s = source(1);
sink(s); // $ hasValueFlow=1
let s = source(2);
sink(s); // $ hasValueFlow=2
}

fn if_expression(cond: bool) {
let a = source(1);
let a = source(3);
let b = 2;
let c = if cond { a } else { b };
sink(c); // $ hasValueFlow=1
sink(c); // $ hasValueFlow=3
}

fn match_expression(m: Option<i64>) {
let a = source(1);
let a = source(4);
let b = match m {
Some(_) => a,
None => 0,
};
sink(b); // $ hasValueFlow=1
sink(b); // $ hasValueFlow=4
}

fn loop_with_break() {
Expand All @@ -42,29 +42,29 @@ fn loop_with_break() {
};
sink(a);
let b = loop {
break source(1);
break source(5);
};
sink(b); // $ hasValueFlow=1
sink(b); // $ hasValueFlow=5
}

fn assignment() {
let mut i = 1;
sink(i);
i = source(2);
sink(i); // $ hasValueFlow=2
i = source(6);
sink(i); // $ hasValueFlow=6
}

// -----------------------------------------------------------------------------
// Data flow through data structures by writing and reading

fn box_deref() {
let i = Box::new(source(1));
sink(*i); // $ MISSING: hasValueFlow=1
let i = Box::new(source(7));
sink(*i); // $ MISSING: hasValueFlow=7
}

fn tuple() {
let a = (source(1), 2);
sink(a.0); // $ MISSING: hasValueFlow=1
let a = (source(8), 2);
sink(a.0); // $ MISSING: hasValueFlow=8
sink(a.1);
}

Expand All @@ -76,35 +76,48 @@ struct Point {

fn struct_field() {
let p = Point {
x: source(1),
x: source(9),
y: 2,
z: source(3),
z: source(10),
};
sink(p.x); // MISSING: hasValueFlow=1
sink(p.x); // $ MISSING: hasValueFlow=9
sink(p.y);
sink(p.z); // MISSING: hasValueFlow=3
sink(p.z); // $ MISSING: hasValueFlow=10
}

// -----------------------------------------------------------------------------
// Data flow through data structures by pattern matching

fn struct_pattern_match() {
let p = Point {
x: source(1),
x: source(11),
y: 2,
z: source(3),
z: source(12),
};
let Point { x: a, y: b, z: c } = p;
sink(a); // MISSING: hasValueFlow=1
sink(a); // $ MISSING: hasValueFlow=11
sink(b);
sink(c); // MISSING: hasValueFlow=3
sink(c); // $ MISSING: hasValueFlow=12
}

fn option_pattern_match() {
let s1 = Some(source(1));
fn option_pattern_match_qualified() {
let s1 = Option::Some(source(13));
let s2 = Option::Some(2);
match s1 {
Option::Some(n) => sink(n), // $ MISSING: hasValueFlow=13
Option::None => sink(0),
}
match s2 {
Option::Some(n) => sink(n),
Option::None => sink(0),
}
}

fn option_pattern_match_unqualified() {
let s1 = Some(source(14));
let s2 = Some(2);
match s1 {
Some(n) => sink(n), // MISSING: hasValueFlow=3
Some(n) => sink(n), // $ MISSING: hasValueFlow=14
None => sink(0),
}
match s2 {
Expand All @@ -113,6 +126,45 @@ fn option_pattern_match() {
}
}

enum MyEnum {
A(i64),
B(i64),
}

fn custom_enum_pattern_match_qualified() {
let s1 = MyEnum::A(source(15));
let s2 = MyEnum::B(2);
match s1 {
MyEnum::A(n) => sink(n), // $ MISSING: hasValueFlow=15
MyEnum::B(n) => sink(n),
}
match s1 {
(MyEnum::A(n) | MyEnum::B(n)) => sink(n), // $ MISSING: hasValueFlow=15
}
match s2 {
MyEnum::A(n) => sink(n),
MyEnum::B(n) => sink(n),
}
}

use crate::MyEnum::*;

fn custom_enum_pattern_match_unqualified() {
let s1 = A(source(16));
let s2 = B(2);
match s1 {
A(n) => sink(n), // $ MISSING: hasValueFlow=16
B(n) => sink(n),
}
match s1 {
(A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16
}
match s2 {
A(n) => sink(n),
B(n) => sink(n),
}
}

fn block_expression1() -> i64 {
let a = { 0 };
a
Expand Down Expand Up @@ -149,7 +201,10 @@ fn main() {
tuple();
struct_field();
struct_pattern_match();
option_pattern_match();
option_pattern_match_qualified();
option_pattern_match_unqualified();
custom_enum_pattern_match_qualified();
custom_enum_pattern_match_unqualified();
block_expression1();
block_expression2(true);
block_expression3(true);
Expand Down

0 comments on commit 5382a02

Please sign in to comment.