зеркало из https://github.com/github/codeql.git
Rust: Add CFG test for early return in `async` block
Also made the test comply with `cargo check`.
This commit is contained in:
Родитель
ef9f3835e5
Коммит
b6103e1ef4
|
@ -0,0 +1,53 @@
|
|||
edges
|
||||
| test.rs:5:5:11:5 | enter test_and_if_let | test.rs:5:24:5:24 | a | |
|
||||
| test.rs:5:5:11:5 | exit test_and_if_let (normal) | test.rs:5:5:11:5 | exit test_and_if_let | |
|
||||
| test.rs:5:24:5:24 | a | test.rs:5:24:5:30 | Param | match |
|
||||
| test.rs:5:24:5:30 | Param | test.rs:5:33:5:33 | b | |
|
||||
| test.rs:5:33:5:33 | b | test.rs:5:33:5:47 | Param | match |
|
||||
| test.rs:5:33:5:47 | Param | test.rs:5:50:5:50 | c | |
|
||||
| test.rs:5:50:5:50 | c | test.rs:5:50:5:56 | Param | match |
|
||||
| test.rs:5:50:5:56 | Param | test.rs:6:12:6:12 | a | |
|
||||
| test.rs:5:67:11:5 | BlockExpr | test.rs:5:5:11:5 | exit test_and_if_let (normal) | |
|
||||
| test.rs:6:9:10:9 | IfExpr | test.rs:5:67:11:5 | BlockExpr | |
|
||||
| test.rs:6:12:6:12 | a | test.rs:6:12:6:31 | [boolean(false)] ... && ... | false |
|
||||
| test.rs:6:12:6:12 | a | test.rs:6:17:6:31 | LetExpr | true |
|
||||
| test.rs:6:12:6:31 | [boolean(false)] ... && ... | test.rs:9:13:9:17 | false | false |
|
||||
| test.rs:6:12:6:31 | [boolean(true)] ... && ... | test.rs:7:13:7:13 | d | true |
|
||||
| test.rs:6:17:6:31 | LetExpr | test.rs:6:31:6:31 | b | |
|
||||
| test.rs:6:21:6:27 | TupleStructPat | test.rs:6:12:6:31 | [boolean(false)] ... && ... | no-match |
|
||||
| test.rs:6:21:6:27 | TupleStructPat | test.rs:6:26:6:26 | d | match |
|
||||
| test.rs:6:26:6:26 | d | test.rs:6:12:6:31 | [boolean(true)] ... && ... | match |
|
||||
| test.rs:6:31:6:31 | b | test.rs:6:21:6:27 | TupleStructPat | |
|
||||
| test.rs:6:33:8:9 | BlockExpr | test.rs:6:9:10:9 | IfExpr | |
|
||||
| test.rs:7:13:7:13 | d | test.rs:6:33:8:9 | BlockExpr | |
|
||||
| test.rs:8:16:10:9 | BlockExpr | test.rs:6:9:10:9 | IfExpr | |
|
||||
| test.rs:9:13:9:17 | false | test.rs:8:16:10:9 | BlockExpr | |
|
||||
| test.rs:13:5:21:5 | enter test_and_if_let2 | test.rs:13:25:13:25 | a | |
|
||||
| test.rs:13:5:21:5 | exit test_and_if_let2 (normal) | test.rs:13:5:21:5 | exit test_and_if_let2 | |
|
||||
| test.rs:13:25:13:25 | a | test.rs:13:25:13:31 | Param | match |
|
||||
| test.rs:13:25:13:31 | Param | test.rs:13:34:13:34 | b | |
|
||||
| test.rs:13:34:13:34 | b | test.rs:13:34:13:39 | Param | match |
|
||||
| test.rs:13:34:13:39 | Param | test.rs:13:42:13:42 | c | |
|
||||
| test.rs:13:42:13:42 | c | test.rs:13:42:13:48 | Param | match |
|
||||
| test.rs:13:42:13:48 | Param | test.rs:14:12:14:12 | a | |
|
||||
| test.rs:13:59:21:5 | BlockExpr | test.rs:13:5:21:5 | exit test_and_if_let2 (normal) | |
|
||||
| test.rs:14:9:20:9 | IfExpr | test.rs:13:59:21:5 | BlockExpr | |
|
||||
| test.rs:14:12:14:12 | a | test.rs:14:12:14:25 | [boolean(false)] ... && ... | false |
|
||||
| test.rs:14:12:14:12 | a | test.rs:14:17:14:25 | LetExpr | true |
|
||||
| test.rs:14:12:14:25 | [boolean(false)] ... && ... | test.rs:14:12:15:16 | [boolean(false)] ... && ... | false |
|
||||
| test.rs:14:12:14:25 | [boolean(true)] ... && ... | test.rs:15:16:15:16 | c | true |
|
||||
| test.rs:14:12:15:16 | [boolean(false)] ... && ... | test.rs:19:13:19:17 | false | false |
|
||||
| test.rs:14:12:15:16 | [boolean(true)] ... && ... | test.rs:17:13:17:13 | d | true |
|
||||
| test.rs:14:17:14:25 | LetExpr | test.rs:14:25:14:25 | b | |
|
||||
| test.rs:14:21:14:21 | d | test.rs:14:12:14:25 | [boolean(true)] ... && ... | match |
|
||||
| test.rs:14:25:14:25 | b | test.rs:14:21:14:21 | d | |
|
||||
| test.rs:15:16:15:16 | c | test.rs:14:12:15:16 | [boolean(false)] ... && ... | false |
|
||||
| test.rs:15:16:15:16 | c | test.rs:14:12:15:16 | [boolean(true)] ... && ... | true |
|
||||
| test.rs:16:9:18:9 | BlockExpr | test.rs:14:9:20:9 | IfExpr | |
|
||||
| test.rs:17:13:17:13 | d | test.rs:17:17:17:17 | 0 | |
|
||||
| test.rs:17:13:17:17 | ... > ... | test.rs:16:9:18:9 | BlockExpr | |
|
||||
| test.rs:17:17:17:17 | 0 | test.rs:17:13:17:17 | ... > ... | |
|
||||
| test.rs:18:16:20:9 | BlockExpr | test.rs:14:9:20:9 | IfExpr | |
|
||||
| test.rs:19:13:19:17 | false | test.rs:18:16:20:9 | BlockExpr | |
|
||||
breakTarget
|
||||
continueTarget
|
|
@ -0,0 +1 @@
|
|||
query: utils/Cfg.ql
|
|
@ -0,0 +1,22 @@
|
|||
// TODO: Move these tests into `controlflow` when they become stable features
|
||||
|
||||
mod if_expression {
|
||||
|
||||
fn test_and_if_let(a: bool, b: Option<bool>, c: bool) -> bool {
|
||||
if a && let Some(d) = b {
|
||||
d
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn test_and_if_let2(a: bool, b: i64, c: bool) -> bool {
|
||||
if a && let d = b
|
||||
&& c
|
||||
{
|
||||
d > 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,10 +1,10 @@
|
|||
use std::collections::HashMap;
|
||||
use std::convert::Infallible;
|
||||
|
||||
mod calls {
|
||||
use crate::test::logical_operators;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn function_call() {
|
||||
test_and_operator(true, false, true);
|
||||
foo::<u32, u64>(42);
|
||||
logical_operators::test_and_operator(true, false, true);
|
||||
method_call();
|
||||
}
|
||||
|
||||
fn method_call() {
|
||||
|
@ -15,6 +15,14 @@ mod calls {
|
|||
|
||||
mod loop_expression {
|
||||
|
||||
fn next(n: i64) -> i64 {
|
||||
if n % 2 == 0 {
|
||||
n / 2
|
||||
} else {
|
||||
3 * n + 1
|
||||
}
|
||||
}
|
||||
|
||||
fn test_break_and_continue(n: i64) -> bool {
|
||||
let mut i = n;
|
||||
loop {
|
||||
|
@ -89,7 +97,7 @@ mod loop_expression {
|
|||
fn test_while_let() {
|
||||
let mut iter = 1..10;
|
||||
while let Some(x) = iter.next() {
|
||||
if (i = 5) {
|
||||
if (x == 5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -136,29 +144,11 @@ mod if_expression {
|
|||
|
||||
fn test_if_let(a: Option<i64>) -> i64 {
|
||||
if let Some(n) = a {
|
||||
n
|
||||
return n;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
fn test_and_if_let(a: bool, b: Option<bool>, c: bool) -> bool {
|
||||
if a && let Some(d) = b {
|
||||
d
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn test_and_if_let2(a: bool, b: i64, c: bool) -> bool {
|
||||
if a && let d = b
|
||||
&& c
|
||||
{
|
||||
d > 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn test_nested_if(a: i64) -> i64 {
|
||||
if (if a < 0 { a < -10 } else { a > 10 }) {
|
||||
1
|
||||
|
@ -191,7 +181,10 @@ mod if_expression {
|
|||
|
||||
fn test_if_assignment(a: i64) -> i64 {
|
||||
let mut x = false;
|
||||
if x = true {
|
||||
if {
|
||||
x = true;
|
||||
x
|
||||
} {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
|
@ -237,7 +230,7 @@ mod if_expression {
|
|||
|
||||
mod logical_operators {
|
||||
|
||||
fn test_and_operator(a: bool, b: bool, c: bool) -> bool {
|
||||
pub fn test_and_operator(a: bool, b: bool, c: bool) -> bool {
|
||||
let d = a && b && c;
|
||||
d
|
||||
}
|
||||
|
@ -257,7 +250,7 @@ mod logical_operators {
|
|||
d
|
||||
}
|
||||
|
||||
fn test_if_and_operator(a: bool, b: i64, c: bool) -> bool {
|
||||
fn test_if_and_operator(a: bool, b: bool, c: bool) -> bool {
|
||||
if a && b && c {
|
||||
true
|
||||
} else {
|
||||
|
@ -265,7 +258,7 @@ mod logical_operators {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_if_or_operator(a: bool, b: i64, c: bool) -> bool {
|
||||
fn test_if_or_operator(a: bool, b: bool, c: bool) -> bool {
|
||||
if a || b || c {
|
||||
true
|
||||
} else {
|
||||
|
@ -287,9 +280,10 @@ mod logical_operators {
|
|||
}
|
||||
|
||||
mod question_mark_operator {
|
||||
use std::num;
|
||||
|
||||
fn test_question_mark_operator_1(s: &str) -> Option<i32> {
|
||||
str.parse::<u32>()? + 4
|
||||
fn test_question_mark_operator_1(s: &str) -> Result<u32, std::num::ParseIntError> {
|
||||
Ok(s.parse::<u32>()? + 4)
|
||||
}
|
||||
|
||||
fn test_question_mark_operator_2(b: Option<bool>) -> Option<bool> {
|
||||
|
@ -301,6 +295,7 @@ mod question_mark_operator {
|
|||
}
|
||||
|
||||
mod match_expression {
|
||||
use std::convert::Infallible;
|
||||
|
||||
fn test_match(maybe_digit: Option<i64>) -> i64 {
|
||||
match maybe_digit {
|
||||
|
@ -321,7 +316,7 @@ mod match_expression {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_match_and(cond: bool, r: Opton<bool>) -> bool {
|
||||
fn test_match_and(cond: bool, r: Option<bool>) -> bool {
|
||||
(match r {
|
||||
Some(a) => a,
|
||||
_ => false,
|
||||
|
@ -338,12 +333,12 @@ mod match_expression {
|
|||
|
||||
mod let_statement {
|
||||
|
||||
fn test_let_match(a: Option<i64>) {
|
||||
let Some(n) = a else { "Expected some" };
|
||||
fn test_let_match(a: Option<i64>) -> i64 {
|
||||
let Some(n) = a else { panic!("Expected some") };
|
||||
n
|
||||
}
|
||||
|
||||
fn test_let_with_return(m: Option<i64>) {
|
||||
fn test_let_with_return(m: Option<i64>) -> bool {
|
||||
let ret = match m {
|
||||
Some(ret) => ret,
|
||||
None => return false,
|
||||
|
@ -354,7 +349,7 @@ mod let_statement {
|
|||
|
||||
mod patterns {
|
||||
|
||||
fn empty_tuple_pattern(unit: ()) -> void {
|
||||
fn empty_tuple_pattern(unit: ()) -> () {
|
||||
let () = unit;
|
||||
return;
|
||||
}
|
||||
|
@ -363,7 +358,7 @@ mod patterns {
|
|||
|
||||
fn empty_struct_pattern(st: MyStruct) -> i64 {
|
||||
match st {
|
||||
MyStruct {} => 1,
|
||||
MyStruct { .. } => 1,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,7 +367,7 @@ mod patterns {
|
|||
..0 => 1,
|
||||
1..2 => 2,
|
||||
5.. => 3,
|
||||
.. => 4,
|
||||
_ => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +375,7 @@ mod patterns {
|
|||
mod divergence {
|
||||
fn test_infinite_loop() -> &'static str {
|
||||
loop {
|
||||
1
|
||||
()
|
||||
}
|
||||
"never reached"
|
||||
}
|
||||
|
@ -391,7 +386,7 @@ mod async_await {
|
|||
println!("hello, world!");
|
||||
}
|
||||
|
||||
async fn async_block() {
|
||||
async fn async_block(b: bool) {
|
||||
let say_godbye = async {
|
||||
println!("godbye, everyone!");
|
||||
};
|
||||
|
@ -403,17 +398,24 @@ mod async_await {
|
|||
say_how_are_you.await;
|
||||
say_godbye.await;
|
||||
noop.await;
|
||||
|
||||
let lambda = |foo| async {
|
||||
if b {
|
||||
return async_block(true);
|
||||
};
|
||||
foo
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mod const_evaluation {
|
||||
const PI: i64 = 3.14159;
|
||||
const PI: f64 = 3.14159;
|
||||
|
||||
const fn add_two(n: i64) -> i64 {
|
||||
n + 2
|
||||
}
|
||||
|
||||
const A_NUMBER: i64 = if add_two(2) + 2 == 4 { PI } else { 0 };
|
||||
const A_NUMBER: f64 = if add_two(2) + 2 == 4 { PI } else { 0.0 };
|
||||
|
||||
fn const_block_assert<T>() -> usize {
|
||||
// If this code ever gets executed, then the assertion has definitely
|
||||
|
@ -444,6 +446,16 @@ fn dead_code() -> i64 {
|
|||
return 1;
|
||||
}
|
||||
|
||||
fn do_thing() {}
|
||||
|
||||
fn condition_not_met() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn do_next_thing() {}
|
||||
|
||||
fn do_last_thing() {}
|
||||
|
||||
fn labelled_block1() -> i64 {
|
||||
let result = 'block: {
|
||||
do_thing();
|
||||
|
@ -457,19 +469,20 @@ fn labelled_block1() -> i64 {
|
|||
do_last_thing();
|
||||
3
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
fn labelled_block2() -> i64 {
|
||||
fn labelled_block2() {
|
||||
let result = 'block: {
|
||||
let x: Option<i64> = None;
|
||||
let Some(y) = x else {
|
||||
break 'block 1;
|
||||
};
|
||||
x
|
||||
0
|
||||
};
|
||||
}
|
||||
|
||||
fn test_nested_function() {
|
||||
fn test_nested_function2() {
|
||||
let mut x = 0;
|
||||
fn nested(x: &mut i64) {
|
||||
*x += 1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче