mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Rust: Add tests for chained let expressions
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
deadEnd
|
||||
| main.rs:30:12:30:12 | x |
|
||||
| main.rs:255:17:255:17 | n |
|
||||
@@ -1,2 +1,2 @@
|
||||
multipleCallTargets
|
||||
| main.rs:445:18:445:24 | n.len() |
|
||||
| main.rs:471:18:471:24 | n.len() |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
#![feature(let_chains)]
|
||||
// Tests for intraprocedural data flow.
|
||||
|
||||
fn source(i: i64) -> i64 {
|
||||
@@ -21,6 +22,19 @@ fn direct() {
|
||||
fn variable_usage() {
|
||||
let s = source(2);
|
||||
sink(s); // $ hasValueFlow=2
|
||||
|
||||
if let x = s {
|
||||
sink(x); // $ MISSING: hasValueFlow=2
|
||||
};
|
||||
|
||||
if let x = s
|
||||
&& {
|
||||
sink(x); // $ MISSING: hasValueFlow=2
|
||||
true
|
||||
}
|
||||
{
|
||||
sink(x); // $ MISSING: hasValueFlow=2
|
||||
};
|
||||
}
|
||||
|
||||
fn if_expression(cond: bool) {
|
||||
@@ -236,6 +250,18 @@ fn option_pattern_match_unqualified() {
|
||||
}
|
||||
}
|
||||
|
||||
fn option_chained_let() {
|
||||
let s1 = Some(source(45));
|
||||
if let Some(n) = s1
|
||||
&& {
|
||||
sink(n); // $ MISSING: hasValueFlow=45
|
||||
true
|
||||
}
|
||||
{
|
||||
sink(n); // $ MISSING: hasValueFlow=45
|
||||
}
|
||||
}
|
||||
|
||||
fn option_unwrap() {
|
||||
let s1 = Some(source(19));
|
||||
sink(s1.unwrap()); // $ hasValueFlow=19
|
||||
@@ -558,6 +584,7 @@ fn main() {
|
||||
struct_nested_match();
|
||||
option_pattern_match_qualified();
|
||||
option_pattern_match_unqualified();
|
||||
option_chained_let();
|
||||
option_unwrap();
|
||||
option_unwrap_or();
|
||||
option_questionmark();
|
||||
|
||||
1
rust/ql/test/library-tests/dataflow/local/options.yml
Normal file
1
rust/ql/test/library-tests/dataflow/local/options.yml
Normal file
@@ -0,0 +1 @@
|
||||
qltest_use_nightly: true
|
||||
@@ -0,0 +1,5 @@
|
||||
deadEnd
|
||||
| main.rs:280:17:280:17 | x |
|
||||
| main.rs:296:17:296:17 | x |
|
||||
| main.rs:315:20:315:20 | x |
|
||||
| main.rs:335:20:335:20 | x |
|
||||
@@ -1,3 +1,3 @@
|
||||
multipleCallTargets
|
||||
| main.rs:87:19:87:40 | ...::from(...) |
|
||||
| main.rs:106:19:106:40 | ...::from(...) |
|
||||
| main.rs:89:19:89:40 | ...::from(...) |
|
||||
| main.rs:111:19:111:40 | ...::from(...) |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
#![feature(let_chains)]
|
||||
#![feature(if_let_guard)]
|
||||
use std::ops::AddAssign;
|
||||
|
||||
fn print_str(s: &str) // s
|
||||
@@ -93,13 +95,16 @@ fn let_pattern3() {
|
||||
}
|
||||
|
||||
fn let_pattern4() {
|
||||
let Some(x5): Option<&str> // x5
|
||||
= Some("x5")
|
||||
|
||||
let x = Some("x5"); // x1
|
||||
let Some(x): Option<&str> // x2
|
||||
= x // $ read_access=x1
|
||||
else {
|
||||
let x = // x3
|
||||
x; // $ read_access=x1
|
||||
print_str(x.unwrap()); // $ read_access=x3
|
||||
todo!()
|
||||
};
|
||||
print_str(x5); // $ read_access=x5
|
||||
print_str(x); // $ read_access=x2
|
||||
}
|
||||
|
||||
fn let_pattern5() {
|
||||
@@ -269,6 +274,90 @@ fn match_pattern9() {
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn match_pattern10() {
|
||||
let x= Some(42); // x1
|
||||
if let Some(x) // x2
|
||||
= x // $ read_access=x1
|
||||
&&
|
||||
x > 0 // $ MISSING: read_access=x2 $ SPURIOUS: read_access=x1
|
||||
{
|
||||
print_i64(x); // $ MISSING: read_access=x2 $ SPURIOUS: read_access=x1
|
||||
} else {
|
||||
let x = // x3
|
||||
x; // $ read_access=x1
|
||||
print_i64(x.unwrap()); // $ read_access=x3
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn match_pattern11() {
|
||||
let x = Some(42); // x1
|
||||
if let Some(x) // x2
|
||||
= x // $ read_access=x1
|
||||
&&
|
||||
let Some(x) // x3
|
||||
= Some(x) // $ MISSING: read_access=x2 $ SPURIOUS: read_access=x1
|
||||
&&
|
||||
x > 0 // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x1
|
||||
{
|
||||
print_i64(x); // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x1
|
||||
} else {
|
||||
let x = // x4
|
||||
x; // $ read_access=x1
|
||||
print_i64(x.unwrap()); // $ read_access=x4
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn match_pattern12() {
|
||||
let x = Some(42); // x1
|
||||
while let Some(x) // x2
|
||||
= x // $ read_access=x1
|
||||
&&
|
||||
let Some(x) // x3
|
||||
= Some(x) // $ MISSING: read_access=x2 $ SPURIOUS: read_access=x1
|
||||
&&
|
||||
x > 0 // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x1
|
||||
{
|
||||
print_i64(x); // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x1
|
||||
break;
|
||||
}
|
||||
|
||||
print_i64(x.unwrap()); // $ read_access=x1
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn match_pattern13() {
|
||||
let x = Some(42); // x1
|
||||
match x { // $ read_access=x1
|
||||
Some(x) // x2
|
||||
if let x // x3
|
||||
= x // $ read_access=x2
|
||||
&& x > 0 => (), // $ MISSING: read_access=x3 $ SPURIOUS: read_access=x2
|
||||
_ => ()
|
||||
}
|
||||
|
||||
print_i64(x.unwrap()); // $ read_access=x1
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn match_pattern14() {
|
||||
let x = Ok(42); // x1
|
||||
if let Err(x) // x2
|
||||
= x // $ read_access=x1
|
||||
{
|
||||
print_i64(x); // $ read_access=x2
|
||||
}
|
||||
else if let Ok(x) // x3
|
||||
= x // $ read_access=x1
|
||||
{
|
||||
print_i64(x); // $ read_access=x3
|
||||
} else {
|
||||
print_i64(x.unwrap()); // $ read_access=x1
|
||||
}
|
||||
}
|
||||
|
||||
fn param_pattern1(
|
||||
a8: &str, // a8
|
||||
(
|
||||
@@ -417,6 +506,7 @@ fn mutate_arg() {
|
||||
let y = // y
|
||||
mutate_param(&mut x); // $ access=x
|
||||
*y = 10; // $ read_access=y
|
||||
|
||||
// prints 10, not 4
|
||||
print_i64(x); // $ read_access=x
|
||||
|
||||
@@ -428,6 +518,7 @@ fn mutate_arg() {
|
||||
w, // $ read_access=w
|
||||
);
|
||||
**w = 11; // $ read_access=w
|
||||
|
||||
// prints 11, not 8
|
||||
print_i64(z); // $ read_access=z
|
||||
}
|
||||
@@ -442,6 +533,7 @@ fn alias() {
|
||||
|
||||
fn capture_immut() {
|
||||
let x = 100; // x
|
||||
|
||||
// Captures immutable value by immutable reference
|
||||
let cap = || {
|
||||
print_i64(x); // $ read_access=x
|
||||
@@ -452,6 +544,7 @@ fn capture_immut() {
|
||||
|
||||
fn capture_mut() {
|
||||
let mut x = 1; // x
|
||||
|
||||
// Captures mutable value by immutable reference
|
||||
let closure1 = || {
|
||||
print_i64(x); // $ read_access=x
|
||||
@@ -460,6 +553,7 @@ fn capture_mut() {
|
||||
print_i64(x); // $ read_access=x
|
||||
|
||||
let mut y = 2; // y
|
||||
|
||||
// Captures mutable value by mutable reference
|
||||
let mut closure2 = || {
|
||||
y = 3; // $ write_access=y
|
||||
@@ -468,6 +562,7 @@ fn capture_mut() {
|
||||
print_i64(y); // $ read_access=y
|
||||
|
||||
let mut z = 2; // z
|
||||
|
||||
// Captures mutable value by mutable reference and calls mutating method
|
||||
let mut closure3 = || {
|
||||
z.add_assign(1); // $ read_access=z
|
||||
@@ -586,6 +681,7 @@ impl MyStruct {
|
||||
fn ref_methodcall_receiver() {
|
||||
let mut a = MyStruct { val: 1 }; // a
|
||||
a.bar(); // $ read_access=a
|
||||
|
||||
// prints 3, not 1
|
||||
print_i64(a.val); // $ read_access=a
|
||||
}
|
||||
@@ -609,6 +705,7 @@ fn macro_invocation() {
|
||||
let_in_macro!(37); // $ read_access=var_in_macro
|
||||
print_i64(var_from_macro); // $ read_access=var_from_macro1
|
||||
let var_in_macro = 33; // var_in_macro1
|
||||
|
||||
// Our analysis does not currently respect the hygiene rules of Rust macros
|
||||
// (https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene.html), because
|
||||
// all we have access to is the expanded AST
|
||||
@@ -653,6 +750,11 @@ fn main() {
|
||||
match_pattern7();
|
||||
match_pattern8();
|
||||
match_pattern9();
|
||||
match_pattern10();
|
||||
match_pattern11();
|
||||
match_pattern12();
|
||||
match_pattern13();
|
||||
match_pattern14();
|
||||
param_pattern1("a", ("b", "c"));
|
||||
param_pattern2(Either::Left(45));
|
||||
destruct_assignment();
|
||||
|
||||
1
rust/ql/test/library-tests/variables/options.yml
Normal file
1
rust/ql/test/library-tests/variables/options.yml
Normal file
@@ -0,0 +1 @@
|
||||
qltest_use_nightly: true
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| main.rs:376:17:376:17 | m |
|
||||
@@ -1,6 +1,6 @@
|
||||
multipleCallTargets
|
||||
| main.rs:13:13:13:29 | ...::from(...) |
|
||||
| main.rs:14:13:14:29 | ...::from(...) |
|
||||
| main.rs:15:13:15:29 | ...::from(...) |
|
||||
| unreachable.rs:165:20:165:42 | ...::from(...) |
|
||||
| unreachable.rs:171:9:171:17 | ...::from(...) |
|
||||
| unreachable.rs:177:17:177:25 | ...::from(...) |
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
| main.rs:10:9:10:9 | a | Variable $@ is assigned a value that is never used. | main.rs:10:9:10:9 | a | a |
|
||||
| main.rs:13:9:13:9 | d | Variable $@ is assigned a value that is never used. | main.rs:13:9:13:9 | d | d |
|
||||
| main.rs:39:5:39:5 | b | Variable $@ is assigned a value that is never used. | main.rs:30:9:30:9 | b | b |
|
||||
| main.rs:41:5:41:5 | c | Variable $@ is assigned a value that is never used. | main.rs:31:13:31:13 | c | c |
|
||||
| main.rs:44:5:44:5 | c | Variable $@ is assigned a value that is never used. | main.rs:31:13:31:13 | c | c |
|
||||
| main.rs:48:9:48:9 | d | Variable $@ is assigned a value that is never used. | main.rs:32:13:32:13 | d | d |
|
||||
| main.rs:54:5:54:5 | e | Variable $@ is assigned a value that is never used. | main.rs:33:13:33:13 | e | e |
|
||||
| main.rs:65:5:65:5 | f | Variable $@ is assigned a value that is never used. | main.rs:34:13:34:13 | f | f |
|
||||
| main.rs:67:5:67:5 | f | Variable $@ is assigned a value that is never used. | main.rs:34:13:34:13 | f | f |
|
||||
| main.rs:69:5:69:5 | g | Variable $@ is assigned a value that is never used. | main.rs:35:9:35:9 | g | g |
|
||||
| main.rs:95:9:95:9 | a | Variable $@ is assigned a value that is never used. | main.rs:95:9:95:9 | a | a |
|
||||
| main.rs:116:9:116:10 | is | Variable $@ is assigned a value that is never used. | main.rs:116:9:116:10 | is | is |
|
||||
| main.rs:139:13:139:17 | total | Variable $@ is assigned a value that is never used. | main.rs:139:13:139:17 | total | total |
|
||||
| main.rs:284:13:284:17 | total | Variable $@ is assigned a value that is never used. | main.rs:252:13:252:17 | total | total |
|
||||
| main.rs:377:9:377:9 | x | Variable $@ is assigned a value that is never used. | main.rs:377:9:377:9 | x | x |
|
||||
| main.rs:385:17:385:17 | x | Variable $@ is assigned a value that is never used. | main.rs:385:17:385:17 | x | x |
|
||||
| main.rs:531:9:531:20 | var_in_macro | Variable $@ is assigned a value that is never used. | main.rs:531:9:531:20 | var_in_macro | var_in_macro |
|
||||
| main.rs:540:9:540:9 | c | Variable $@ is assigned a value that is never used. | main.rs:540:9:540:9 | c | c |
|
||||
| main.rs:11:9:11:9 | a | Variable $@ is assigned a value that is never used. | main.rs:11:9:11:9 | a | a |
|
||||
| main.rs:14:9:14:9 | d | Variable $@ is assigned a value that is never used. | main.rs:14:9:14:9 | d | d |
|
||||
| main.rs:40:5:40:5 | b | Variable $@ is assigned a value that is never used. | main.rs:31:9:31:9 | b | b |
|
||||
| main.rs:42:5:42:5 | c | Variable $@ is assigned a value that is never used. | main.rs:32:13:32:13 | c | c |
|
||||
| main.rs:45:5:45:5 | c | Variable $@ is assigned a value that is never used. | main.rs:32:13:32:13 | c | c |
|
||||
| main.rs:49:9:49:9 | d | Variable $@ is assigned a value that is never used. | main.rs:33:13:33:13 | d | d |
|
||||
| main.rs:55:5:55:5 | e | Variable $@ is assigned a value that is never used. | main.rs:34:13:34:13 | e | e |
|
||||
| main.rs:66:5:66:5 | f | Variable $@ is assigned a value that is never used. | main.rs:35:13:35:13 | f | f |
|
||||
| main.rs:68:5:68:5 | f | Variable $@ is assigned a value that is never used. | main.rs:35:13:35:13 | f | f |
|
||||
| main.rs:70:5:70:5 | g | Variable $@ is assigned a value that is never used. | main.rs:36:9:36:9 | g | g |
|
||||
| main.rs:96:9:96:9 | a | Variable $@ is assigned a value that is never used. | main.rs:96:9:96:9 | a | a |
|
||||
| main.rs:117:9:117:10 | is | Variable $@ is assigned a value that is never used. | main.rs:117:9:117:10 | is | is |
|
||||
| main.rs:140:13:140:17 | total | Variable $@ is assigned a value that is never used. | main.rs:140:13:140:17 | total | total |
|
||||
| main.rs:285:13:285:17 | total | Variable $@ is assigned a value that is never used. | main.rs:253:13:253:17 | total | total |
|
||||
| main.rs:382:9:382:9 | x | Variable $@ is assigned a value that is never used. | main.rs:382:9:382:9 | x | x |
|
||||
| main.rs:390:17:390:17 | x | Variable $@ is assigned a value that is never used. | main.rs:390:17:390:17 | x | x |
|
||||
| main.rs:536:9:536:20 | var_in_macro | Variable $@ is assigned a value that is never used. | main.rs:536:9:536:20 | var_in_macro | var_in_macro |
|
||||
| main.rs:545:9:545:9 | c | Variable $@ is assigned a value that is never used. | main.rs:545:9:545:9 | c | c |
|
||||
| more.rs:44:9:44:14 | a_ptr4 | Variable $@ is assigned a value that is never used. | more.rs:44:9:44:14 | a_ptr4 | a_ptr4 |
|
||||
| more.rs:59:9:59:13 | d_ptr | Variable $@ is assigned a value that is never used. | more.rs:59:9:59:13 | d_ptr | d_ptr |
|
||||
| more.rs:65:13:65:17 | f_ptr | Variable $@ is assigned a value that is never used. | more.rs:65:13:65:17 | f_ptr | f_ptr |
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
| main.rs:29:9:29:9 | a | Variable 'a' is not used. |
|
||||
| main.rs:98:13:98:13 | d | Variable 'd' is not used. |
|
||||
| main.rs:147:5:147:5 | y | Variable 'y' is not used. |
|
||||
| main.rs:174:9:174:9 | x | Variable 'x' is not used. |
|
||||
| main.rs:254:17:254:17 | a | Variable 'a' is not used. |
|
||||
| main.rs:262:20:262:22 | val | Variable 'val' is not used. |
|
||||
| main.rs:276:14:276:16 | val | Variable 'val' is not used. |
|
||||
| main.rs:291:22:291:24 | val | Variable 'val' is not used. |
|
||||
| main.rs:298:24:298:26 | val | Variable 'val' is not used. |
|
||||
| main.rs:306:13:306:15 | num | Variable 'num' is not used. |
|
||||
| main.rs:321:12:321:12 | j | Variable 'j' is not used. |
|
||||
| main.rs:341:25:341:25 | y | Variable 'y' is not used. |
|
||||
| main.rs:344:28:344:28 | a | Variable 'a' is not used. |
|
||||
| main.rs:347:9:347:9 | p | Variable 'p' is not used. |
|
||||
| main.rs:365:9:365:13 | right | Variable 'right' is not used. |
|
||||
| main.rs:371:9:371:14 | right2 | Variable 'right2' is not used. |
|
||||
| main.rs:378:13:378:13 | y | Variable 'y' is not used. |
|
||||
| main.rs:386:21:386:21 | y | Variable 'y' is not used. |
|
||||
| main.rs:431:26:431:28 | val | Variable 'val' is not used. |
|
||||
| main.rs:434:21:434:23 | acc | Variable 'acc' is not used. |
|
||||
| main.rs:455:9:455:14 | unused | Variable 'unused' is not used. |
|
||||
| main.rs:30:9:30:9 | a | Variable 'a' is not used. |
|
||||
| main.rs:99:13:99:13 | d | Variable 'd' is not used. |
|
||||
| main.rs:148:5:148:5 | y | Variable 'y' is not used. |
|
||||
| main.rs:175:9:175:9 | x | Variable 'x' is not used. |
|
||||
| main.rs:255:17:255:17 | a | Variable 'a' is not used. |
|
||||
| main.rs:263:20:263:22 | val | Variable 'val' is not used. |
|
||||
| main.rs:277:14:277:16 | val | Variable 'val' is not used. |
|
||||
| main.rs:292:22:292:24 | val | Variable 'val' is not used. |
|
||||
| main.rs:299:24:299:26 | val | Variable 'val' is not used. |
|
||||
| main.rs:307:13:307:15 | num | Variable 'num' is not used. |
|
||||
| main.rs:322:12:322:12 | j | Variable 'j' is not used. |
|
||||
| main.rs:342:25:342:25 | y | Variable 'y' is not used. |
|
||||
| main.rs:345:28:345:28 | a | Variable 'a' is not used. |
|
||||
| main.rs:348:9:348:9 | p | Variable 'p' is not used. |
|
||||
| main.rs:366:9:366:13 | right | Variable 'right' is not used. |
|
||||
| main.rs:372:9:372:14 | right2 | Variable 'right2' is not used. |
|
||||
| main.rs:376:17:376:17 | m | Variable 'm' is not used. |
|
||||
| main.rs:383:13:383:13 | y | Variable 'y' is not used. |
|
||||
| main.rs:391:21:391:21 | y | Variable 'y' is not used. |
|
||||
| main.rs:436:26:436:28 | val | Variable 'val' is not used. |
|
||||
| main.rs:439:21:439:23 | acc | Variable 'acc' is not used. |
|
||||
| main.rs:460:9:460:14 | unused | Variable 'unused' is not used. |
|
||||
| more.rs:24:9:24:11 | val | Variable 'val' is not used. |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#![feature(let_chains)]
|
||||
mod more;
|
||||
mod unreachable;
|
||||
|
||||
@@ -371,6 +372,10 @@ fn if_lets_matches() {
|
||||
right2) = // $ MISSING: Alert[rust/unused-value] $ SPURIOUS: Alert[rust/unused-variable]
|
||||
pair;
|
||||
_ = left2;
|
||||
|
||||
if let Some(m) = Some(10) // $ SPURIOUS: Alert[rust/unused-variable]
|
||||
&& m > 0
|
||||
{}
|
||||
}
|
||||
|
||||
fn shadowing() -> i32 {
|
||||
|
||||
1
rust/ql/test/query-tests/unusedentities/options.yml
Normal file
1
rust/ql/test/query-tests/unusedentities/options.yml
Normal file
@@ -0,0 +1 @@
|
||||
qltest_use_nightly: true
|
||||
Reference in New Issue
Block a user