Summary: public C++ allows to have one variable declared+initialized as a condition statement. Handle these cases properly for `if` and `while` statements. Reviewed By: dulmarod Differential Revision: D2625774 fb-gh-sync-id: bac95b8master
parent
0db83eb5dd
commit
db35afef1e
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
int simple_init() {
|
||||
int result = 0;
|
||||
for (int i = 0; int x = 2; i++) {
|
||||
result += x;
|
||||
}
|
||||
}
|
||||
|
||||
int init_with_scoped_var() {
|
||||
int result = 0;
|
||||
for (int i = 10; int x = i; i--) {
|
||||
result += x;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
digraph iCFG {
|
||||
20 [label="20: DeclStmt \n *&result:int =0 [line 18]\n " shape="box"]
|
||||
|
||||
|
||||
20 -> 14 ;
|
||||
19 [label="19: ComppoundAssignStmt \n n$3=*&x:int [line 20]\n n$4=*&result:int [line 20]\n *&result:int =(n$4 + n$3) [line 20]\n REMOVE_TEMPS(n$3,n$4); [line 20]\n NULLIFY(&x,false); [line 20]\n " shape="box"]
|
||||
|
||||
|
||||
19 -> 15 ;
|
||||
18 [label="18: DeclStmt \n n$2=*&i:int [line 19]\n *&x:int =n$2 [line 19]\n REMOVE_TEMPS(n$2); [line 19]\n " shape="box"]
|
||||
|
||||
|
||||
18 -> 16 ;
|
||||
18 -> 17 ;
|
||||
17 [label="17: Prune (false branch) \n n$1=*&x:int [line 19]\n PRUNE((n$1 == 0), false); [line 19]\n REMOVE_TEMPS(n$1); [line 19]\n NULLIFY(&i,false); [line 19]\n NULLIFY(&result,false); [line 19]\n NULLIFY(&x,false); [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="invhouse"]
|
||||
|
||||
|
||||
17 -> 12 ;
|
||||
16 [label="16: Prune (true branch) \n n$1=*&x:int [line 19]\n PRUNE((n$1 != 0), true); [line 19]\n REMOVE_TEMPS(n$1); [line 19]\n " shape="invhouse"]
|
||||
|
||||
|
||||
16 -> 19 ;
|
||||
15 [label="15: UnaryOperator \n n$0=*&i:int [line 19]\n *&i:int =(n$0 - 1) [line 19]\n REMOVE_TEMPS(n$0); [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"]
|
||||
|
||||
|
||||
15 -> 13 ;
|
||||
14 [label="14: DeclStmt \n *&i:int =10 [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"]
|
||||
|
||||
|
||||
14 -> 13 ;
|
||||
13 [label="13: + \n " ]
|
||||
|
||||
|
||||
13 -> 18 ;
|
||||
12 [label="12: Exit init_with_scoped_var \n " color=yellow style=filled]
|
||||
|
||||
|
||||
11 [label="11: Start init_with_scoped_var\nFormals: \nLocals: i:int x:int result:int \n DECLARE_LOCALS(&return,&i,&x,&result); [line 17]\n NULLIFY(&i,false); [line 17]\n NULLIFY(&result,false); [line 17]\n NULLIFY(&x,false); [line 17]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
11 -> 20 ;
|
||||
10 [label="10: DeclStmt \n *&result:int =0 [line 11]\n " shape="box"]
|
||||
|
||||
|
||||
10 -> 4 ;
|
||||
9 [label="9: ComppoundAssignStmt \n n$2=*&x:int [line 13]\n n$3=*&result:int [line 13]\n *&result:int =(n$3 + n$2) [line 13]\n REMOVE_TEMPS(n$2,n$3); [line 13]\n NULLIFY(&x,false); [line 13]\n " shape="box"]
|
||||
|
||||
|
||||
9 -> 5 ;
|
||||
8 [label="8: DeclStmt \n *&x:int =2 [line 12]\n " shape="box"]
|
||||
|
||||
|
||||
8 -> 6 ;
|
||||
8 -> 7 ;
|
||||
7 [label="7: Prune (false branch) \n n$1=*&x:int [line 12]\n PRUNE((n$1 == 0), false); [line 12]\n REMOVE_TEMPS(n$1); [line 12]\n NULLIFY(&i,false); [line 12]\n NULLIFY(&result,false); [line 12]\n NULLIFY(&x,false); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="invhouse"]
|
||||
|
||||
|
||||
7 -> 2 ;
|
||||
6 [label="6: Prune (true branch) \n n$1=*&x:int [line 12]\n PRUNE((n$1 != 0), true); [line 12]\n REMOVE_TEMPS(n$1); [line 12]\n " shape="invhouse"]
|
||||
|
||||
|
||||
6 -> 9 ;
|
||||
5 [label="5: UnaryOperator \n n$0=*&i:int [line 12]\n *&i:int =(n$0 + 1) [line 12]\n REMOVE_TEMPS(n$0); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"]
|
||||
|
||||
|
||||
5 -> 3 ;
|
||||
4 [label="4: DeclStmt \n *&i:int =0 [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"]
|
||||
|
||||
|
||||
4 -> 3 ;
|
||||
3 [label="3: + \n " ]
|
||||
|
||||
|
||||
3 -> 8 ;
|
||||
2 [label="2: Exit simple_init \n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 [label="1: Start simple_init\nFormals: \nLocals: i:int x:int result:int \n DECLARE_LOCALS(&return,&i,&x,&result); [line 10]\n NULLIFY(&i,false); [line 10]\n NULLIFY(&result,false); [line 10]\n NULLIFY(&x,false); [line 10]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 -> 10 ;
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
int simple_init_div1() {
|
||||
if (int a = 1) {
|
||||
return 1/a;
|
||||
}
|
||||
}
|
||||
|
||||
int simple_init_div0() {
|
||||
if (int a = 0) {
|
||||
return a;
|
||||
} else {
|
||||
return 1/a;
|
||||
}
|
||||
}
|
||||
|
||||
int simple_inif_elseif_div0() {
|
||||
if (int a = 0) {
|
||||
return 1;
|
||||
} else if (int b = 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 1 / (a + b);
|
||||
}
|
||||
}
|
||||
|
||||
int get1() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int function_call_init_div0() {
|
||||
if (int a = get1()) {
|
||||
return 1 / (a - 1);
|
||||
}
|
||||
}
|
||||
|
||||
int conditional_init_div0() {
|
||||
if (int a = 1 ? 1 : 0) {
|
||||
return 1 / (a - 1);
|
||||
}
|
||||
}
|
||||
|
||||
int reference_init_div0() {
|
||||
int r = 1;
|
||||
if (int& a = r) {
|
||||
a = 0;
|
||||
}
|
||||
return 1/r;
|
||||
}
|
||||
|
||||
int simple_init_null_deref() {
|
||||
if (int *p = nullptr) {
|
||||
return 1;
|
||||
} else {
|
||||
return *p;
|
||||
}
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
digraph iCFG {
|
||||
67 [label="67: Return Stmt \n n$1=*&p:int * [line 62]\n n$2=*n$1:int [line 62]\n *&return:int =n$2 [line 62]\n REMOVE_TEMPS(n$1,n$2); [line 62]\n NULLIFY(&p,false); [line 62]\n APPLY_ABSTRACTION; [line 62]\n " shape="box"]
|
||||
|
||||
|
||||
67 -> 61 ;
|
||||
66 [label="66: Return Stmt \n NULLIFY(&p,false); [line 60]\n *&return:int =1 [line 60]\n APPLY_ABSTRACTION; [line 60]\n " shape="box"]
|
||||
|
||||
|
||||
66 -> 61 ;
|
||||
65 [label="65: DeclStmt \n *&p:int *=null [line 59]\n " shape="box"]
|
||||
|
||||
|
||||
65 -> 63 ;
|
||||
65 -> 64 ;
|
||||
64 [label="64: Prune (false branch) \n n$0=*&p:int * [line 59]\n PRUNE((n$0 == 0), false); [line 59]\n REMOVE_TEMPS(n$0); [line 59]\n " shape="invhouse"]
|
||||
|
||||
|
||||
64 -> 67 ;
|
||||
63 [label="63: Prune (true branch) \n n$0=*&p:int * [line 59]\n PRUNE((n$0 != 0), true); [line 59]\n REMOVE_TEMPS(n$0); [line 59]\n " shape="invhouse"]
|
||||
|
||||
|
||||
63 -> 66 ;
|
||||
62 [label="62: + \n NULLIFY(&p,false); [line 59]\n " ]
|
||||
|
||||
|
||||
62 -> 61 ;
|
||||
61 [label="61: Exit simple_init_null_deref \n " color=yellow style=filled]
|
||||
|
||||
|
||||
60 [label="60: Start simple_init_null_deref\nFormals: \nLocals: p:int * \n DECLARE_LOCALS(&return,&p); [line 58]\n NULLIFY(&p,false); [line 58]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
60 -> 65 ;
|
||||
59 [label="59: DeclStmt \n *&r:int =1 [line 51]\n " shape="box"]
|
||||
|
||||
|
||||
59 -> 57 ;
|
||||
58 [label="58: BinaryOperatorStmt: Assign \n n$3=*&a:int & [line 53]\n *n$3:int =0 [line 53]\n REMOVE_TEMPS(n$3); [line 53]\n NULLIFY(&a,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"]
|
||||
|
||||
|
||||
58 -> 54 ;
|
||||
57 [label="57: DeclStmt \n *&a:int &=&r [line 52]\n " shape="box"]
|
||||
|
||||
|
||||
57 -> 55 ;
|
||||
57 -> 56 ;
|
||||
56 [label="56: Prune (false branch) \n n$1=*&a:int & [line 52]\n n$2=*n$1:int [line 52]\n PRUNE((n$2 == 0), false); [line 52]\n REMOVE_TEMPS(n$1,n$2); [line 52]\n APPLY_ABSTRACTION; [line 52]\n " shape="invhouse"]
|
||||
|
||||
|
||||
56 -> 54 ;
|
||||
55 [label="55: Prune (true branch) \n n$1=*&a:int & [line 52]\n n$2=*n$1:int [line 52]\n PRUNE((n$2 != 0), true); [line 52]\n REMOVE_TEMPS(n$1,n$2); [line 52]\n " shape="invhouse"]
|
||||
|
||||
|
||||
55 -> 58 ;
|
||||
54 [label="54: + \n " ]
|
||||
|
||||
|
||||
54 -> 53 ;
|
||||
53 [label="53: Return Stmt \n NULLIFY(&a,false); [line 55]\n n$0=*&r:int [line 55]\n *&return:int =(1 / n$0) [line 55]\n REMOVE_TEMPS(n$0); [line 55]\n NULLIFY(&r,false); [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="box"]
|
||||
|
||||
|
||||
53 -> 52 ;
|
||||
52 [label="52: Exit reference_init_div0 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
51 [label="51: Start reference_init_div0\nFormals: \nLocals: a:int & r:int \n DECLARE_LOCALS(&return,&a,&r); [line 50]\n NULLIFY(&a,false); [line 50]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
51 -> 59 ;
|
||||
50 [label="50: Return Stmt \n n$2=*&a:int [line 46]\n *&return:int =(1 / (n$2 - 1)) [line 46]\n REMOVE_TEMPS(n$2); [line 46]\n NULLIFY(&a,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"]
|
||||
|
||||
|
||||
50 -> 40 ;
|
||||
49 [label="49: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___45); [line 45]\n *&SIL_temp_conditional___45:int =0 [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"]
|
||||
|
||||
|
||||
49 -> 45 ;
|
||||
48 [label="48: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___45); [line 45]\n *&SIL_temp_conditional___45:int =1 [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"]
|
||||
|
||||
|
||||
48 -> 45 ;
|
||||
47 [label="47: Prune (false branch) \n PRUNE((1 == 0), false); [line 45]\n " shape="invhouse"]
|
||||
|
||||
|
||||
47 -> 49 ;
|
||||
46 [label="46: Prune (true branch) \n PRUNE((1 != 0), true); [line 45]\n " shape="invhouse"]
|
||||
|
||||
|
||||
46 -> 48 ;
|
||||
45 [label="45: + \n " ]
|
||||
|
||||
|
||||
45 -> 44 ;
|
||||
44 [label="44: DeclStmt \n n$1=*&SIL_temp_conditional___45:int [line 45]\n NULLIFY(&SIL_temp_conditional___45,true); [line 45]\n *&a:int =n$1 [line 45]\n REMOVE_TEMPS(n$1); [line 45]\n " shape="box"]
|
||||
|
||||
|
||||
44 -> 42 ;
|
||||
44 -> 43 ;
|
||||
43 [label="43: Prune (false branch) \n n$0=*&a:int [line 45]\n PRUNE((n$0 == 0), false); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"]
|
||||
|
||||
|
||||
43 -> 41 ;
|
||||
42 [label="42: Prune (true branch) \n n$0=*&a:int [line 45]\n PRUNE((n$0 != 0), true); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"]
|
||||
|
||||
|
||||
42 -> 50 ;
|
||||
41 [label="41: + \n NULLIFY(&a,false); [line 45]\n " ]
|
||||
|
||||
|
||||
41 -> 40 ;
|
||||
40 [label="40: Exit conditional_init_div0 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
39 [label="39: Start conditional_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 44]\n NULLIFY(&a,false); [line 44]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
39 -> 46 ;
|
||||
39 -> 47 ;
|
||||
38 [label="38: Return Stmt \n n$2=*&a:int [line 40]\n *&return:int =(1 / (n$2 - 1)) [line 40]\n REMOVE_TEMPS(n$2); [line 40]\n NULLIFY(&a,false); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"]
|
||||
|
||||
|
||||
38 -> 33 ;
|
||||
37 [label="37: DeclStmt \n n$1=_fun_get1() [line 39]\n *&a:int =n$1 [line 39]\n REMOVE_TEMPS(n$1); [line 39]\n " shape="box"]
|
||||
|
||||
|
||||
37 -> 35 ;
|
||||
37 -> 36 ;
|
||||
36 [label="36: Prune (false branch) \n n$0=*&a:int [line 39]\n PRUNE((n$0 == 0), false); [line 39]\n REMOVE_TEMPS(n$0); [line 39]\n " shape="invhouse"]
|
||||
|
||||
|
||||
36 -> 34 ;
|
||||
35 [label="35: Prune (true branch) \n n$0=*&a:int [line 39]\n PRUNE((n$0 != 0), true); [line 39]\n REMOVE_TEMPS(n$0); [line 39]\n " shape="invhouse"]
|
||||
|
||||
|
||||
35 -> 38 ;
|
||||
34 [label="34: + \n NULLIFY(&a,false); [line 39]\n " ]
|
||||
|
||||
|
||||
34 -> 33 ;
|
||||
33 [label="33: Exit function_call_init_div0 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
32 [label="32: Start function_call_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 38]\n NULLIFY(&a,false); [line 38]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
32 -> 37 ;
|
||||
31 [label="31: Return Stmt \n *&return:int =1 [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"]
|
||||
|
||||
|
||||
31 -> 30 ;
|
||||
30 [label="30: Exit get1 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
29 [label="29: Start get1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 34]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
29 -> 31 ;
|
||||
28 [label="28: Return Stmt \n n$2=*&a:int [line 30]\n n$3=*&b:int [line 30]\n *&return:int =(1 / (n$2 + n$3)) [line 30]\n REMOVE_TEMPS(n$2,n$3); [line 30]\n NULLIFY(&a,false); [line 30]\n NULLIFY(&b,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"]
|
||||
|
||||
|
||||
28 -> 17 ;
|
||||
27 [label="27: Return Stmt \n NULLIFY(&a,false); [line 28]\n NULLIFY(&b,false); [line 28]\n *&return:int =1 [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"]
|
||||
|
||||
|
||||
27 -> 17 ;
|
||||
26 [label="26: DeclStmt \n *&b:int =0 [line 27]\n " shape="box"]
|
||||
|
||||
|
||||
26 -> 24 ;
|
||||
26 -> 25 ;
|
||||
25 [label="25: Prune (false branch) \n n$1=*&b:int [line 27]\n PRUNE((n$1 == 0), false); [line 27]\n REMOVE_TEMPS(n$1); [line 27]\n " shape="invhouse"]
|
||||
|
||||
|
||||
25 -> 28 ;
|
||||
24 [label="24: Prune (true branch) \n n$1=*&b:int [line 27]\n PRUNE((n$1 != 0), true); [line 27]\n REMOVE_TEMPS(n$1); [line 27]\n " shape="invhouse"]
|
||||
|
||||
|
||||
24 -> 27 ;
|
||||
23 [label="23: + \n " ]
|
||||
|
||||
|
||||
23 -> 18 ;
|
||||
22 [label="22: Return Stmt \n NULLIFY(&a,false); [line 26]\n *&return:int =1 [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"]
|
||||
|
||||
|
||||
22 -> 17 ;
|
||||
21 [label="21: DeclStmt \n *&a:int =0 [line 25]\n " shape="box"]
|
||||
|
||||
|
||||
21 -> 19 ;
|
||||
21 -> 20 ;
|
||||
20 [label="20: Prune (false branch) \n n$0=*&a:int [line 25]\n PRUNE((n$0 == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"]
|
||||
|
||||
|
||||
20 -> 26 ;
|
||||
19 [label="19: Prune (true branch) \n n$0=*&a:int [line 25]\n PRUNE((n$0 != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"]
|
||||
|
||||
|
||||
19 -> 22 ;
|
||||
18 [label="18: + \n NULLIFY(&a,false); [line 25]\n NULLIFY(&b,false); [line 25]\n " ]
|
||||
|
||||
|
||||
18 -> 17 ;
|
||||
17 [label="17: Exit simple_inif_elseif_div0 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
16 [label="16: Start simple_inif_elseif_div0\nFormals: \nLocals: a:int b:int \n DECLARE_LOCALS(&return,&a,&b); [line 24]\n NULLIFY(&a,false); [line 24]\n NULLIFY(&b,false); [line 24]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
16 -> 21 ;
|
||||
15 [label="15: Return Stmt \n n$2=*&a:int [line 20]\n *&return:int =(1 / n$2) [line 20]\n REMOVE_TEMPS(n$2); [line 20]\n NULLIFY(&a,false); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="box"]
|
||||
|
||||
|
||||
15 -> 9 ;
|
||||
14 [label="14: Return Stmt \n n$1=*&a:int [line 18]\n *&return:int =n$1 [line 18]\n REMOVE_TEMPS(n$1); [line 18]\n NULLIFY(&a,false); [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"]
|
||||
|
||||
|
||||
14 -> 9 ;
|
||||
13 [label="13: DeclStmt \n *&a:int =0 [line 17]\n " shape="box"]
|
||||
|
||||
|
||||
13 -> 11 ;
|
||||
13 -> 12 ;
|
||||
12 [label="12: Prune (false branch) \n n$0=*&a:int [line 17]\n PRUNE((n$0 == 0), false); [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n " shape="invhouse"]
|
||||
|
||||
|
||||
12 -> 15 ;
|
||||
11 [label="11: Prune (true branch) \n n$0=*&a:int [line 17]\n PRUNE((n$0 != 0), true); [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n " shape="invhouse"]
|
||||
|
||||
|
||||
11 -> 14 ;
|
||||
10 [label="10: + \n NULLIFY(&a,false); [line 17]\n " ]
|
||||
|
||||
|
||||
10 -> 9 ;
|
||||
9 [label="9: Exit simple_init_div0 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
8 [label="8: Start simple_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 16]\n NULLIFY(&a,false); [line 16]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
8 -> 13 ;
|
||||
7 [label="7: Return Stmt \n n$1=*&a:int [line 12]\n *&return:int =(1 / n$1) [line 12]\n REMOVE_TEMPS(n$1); [line 12]\n NULLIFY(&a,false); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"]
|
||||
|
||||
|
||||
7 -> 2 ;
|
||||
6 [label="6: DeclStmt \n *&a:int =1 [line 11]\n " shape="box"]
|
||||
|
||||
|
||||
6 -> 4 ;
|
||||
6 -> 5 ;
|
||||
5 [label="5: Prune (false branch) \n n$0=*&a:int [line 11]\n PRUNE((n$0 == 0), false); [line 11]\n REMOVE_TEMPS(n$0); [line 11]\n " shape="invhouse"]
|
||||
|
||||
|
||||
5 -> 3 ;
|
||||
4 [label="4: Prune (true branch) \n n$0=*&a:int [line 11]\n PRUNE((n$0 != 0), true); [line 11]\n REMOVE_TEMPS(n$0); [line 11]\n " shape="invhouse"]
|
||||
|
||||
|
||||
4 -> 7 ;
|
||||
3 [label="3: + \n NULLIFY(&a,false); [line 11]\n " ]
|
||||
|
||||
|
||||
3 -> 2 ;
|
||||
2 [label="2: Exit simple_init_div1 \n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 [label="1: Start simple_init_div1\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 10]\n NULLIFY(&a,false); [line 10]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 -> 6 ;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
int simple_assignment() {
|
||||
int x = 10;
|
||||
int result = 0;
|
||||
while(int a = x) {
|
||||
result += a;
|
||||
x -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conditional_assignment() {
|
||||
int x = 10;
|
||||
int result = 0;
|
||||
while(int a = x > 0 ? x : 0) {
|
||||
result += a;
|
||||
x -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
digraph iCFG {
|
||||
28 [label="28: DeclStmt \n *&x:int =10 [line 21]\n " shape="box"]
|
||||
|
||||
|
||||
28 -> 27 ;
|
||||
27 [label="27: DeclStmt \n *&result:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"]
|
||||
|
||||
|
||||
27 -> 15 ;
|
||||
26 [label="26: ComppoundAssignStmt \n n$5=*&a:int [line 24]\n n$6=*&result:int [line 24]\n *&result:int =(n$6 + n$5) [line 24]\n REMOVE_TEMPS(n$5,n$6); [line 24]\n NULLIFY(&a,false); [line 24]\n " shape="box"]
|
||||
|
||||
|
||||
26 -> 25 ;
|
||||
25 [label="25: ComppoundAssignStmt \n n$4=*&x:int [line 25]\n *&x:int =(n$4 - 1) [line 25]\n REMOVE_TEMPS(n$4); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"]
|
||||
|
||||
|
||||
25 -> 15 ;
|
||||
24 [label="24: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___19); [line 23]\n *&SIL_temp_conditional___19:int =0 [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"]
|
||||
|
||||
|
||||
24 -> 19 ;
|
||||
23 [label="23: ConditinalStmt Branch \n n$2=*&x:int [line 23]\n DECLARE_LOCALS(&SIL_temp_conditional___19); [line 23]\n *&SIL_temp_conditional___19:int =n$2 [line 23]\n REMOVE_TEMPS(n$2); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"]
|
||||
|
||||
|
||||
23 -> 19 ;
|
||||
22 [label="22: Prune (false branch) \n PRUNE(((n$1 > 0) == 0), false); [line 23]\n REMOVE_TEMPS(n$1); [line 23]\n " shape="invhouse"]
|
||||
|
||||
|
||||
22 -> 24 ;
|
||||
21 [label="21: Prune (true branch) \n PRUNE(((n$1 > 0) != 0), true); [line 23]\n REMOVE_TEMPS(n$1); [line 23]\n " shape="invhouse"]
|
||||
|
||||
|
||||
21 -> 23 ;
|
||||
20 [label="20: BinaryOperatorStmt: GT \n n$1=*&x:int [line 23]\n " shape="box"]
|
||||
|
||||
|
||||
20 -> 21 ;
|
||||
20 -> 22 ;
|
||||
19 [label="19: + \n " ]
|
||||
|
||||
|
||||
19 -> 18 ;
|
||||
18 [label="18: DeclStmt \n n$3=*&SIL_temp_conditional___19:int [line 23]\n NULLIFY(&SIL_temp_conditional___19,true); [line 23]\n *&a:int =n$3 [line 23]\n REMOVE_TEMPS(n$3); [line 23]\n " shape="box"]
|
||||
|
||||
|
||||
18 -> 16 ;
|
||||
18 -> 17 ;
|
||||
17 [label="17: Prune (false branch) \n n$0=*&a:int [line 23]\n PRUNE((n$0 == 0), false); [line 23]\n REMOVE_TEMPS(n$0); [line 23]\n " shape="invhouse"]
|
||||
|
||||
|
||||
17 -> 14 ;
|
||||
16 [label="16: Prune (true branch) \n n$0=*&a:int [line 23]\n PRUNE((n$0 != 0), true); [line 23]\n REMOVE_TEMPS(n$0); [line 23]\n " shape="invhouse"]
|
||||
|
||||
|
||||
16 -> 26 ;
|
||||
15 [label="15: + \n " ]
|
||||
|
||||
|
||||
15 -> 20 ;
|
||||
14 [label="14: Return Stmt \n NULLIFY(&a,false); [line 27]\n NULLIFY(&result,false); [line 27]\n NULLIFY(&x,false); [line 27]\n *&return:int =0 [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"]
|
||||
|
||||
|
||||
14 -> 13 ;
|
||||
13 [label="13: Exit conditional_assignment \n " color=yellow style=filled]
|
||||
|
||||
|
||||
12 [label="12: Start conditional_assignment\nFormals: \nLocals: a:int result:int x:int \n DECLARE_LOCALS(&return,&a,&result,&x); [line 20]\n NULLIFY(&a,false); [line 20]\n NULLIFY(&result,false); [line 20]\n NULLIFY(&x,false); [line 20]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
12 -> 28 ;
|
||||
11 [label="11: DeclStmt \n *&x:int =10 [line 11]\n " shape="box"]
|
||||
|
||||
|
||||
11 -> 10 ;
|
||||
10 [label="10: DeclStmt \n *&result:int =0 [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"]
|
||||
|
||||
|
||||
10 -> 4 ;
|
||||
9 [label="9: ComppoundAssignStmt \n n$3=*&a:int [line 14]\n n$4=*&result:int [line 14]\n *&result:int =(n$4 + n$3) [line 14]\n REMOVE_TEMPS(n$3,n$4); [line 14]\n NULLIFY(&a,false); [line 14]\n " shape="box"]
|
||||
|
||||
|
||||
9 -> 8 ;
|
||||
8 [label="8: ComppoundAssignStmt \n n$2=*&x:int [line 15]\n *&x:int =(n$2 - 1) [line 15]\n REMOVE_TEMPS(n$2); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"]
|
||||
|
||||
|
||||
8 -> 4 ;
|
||||
7 [label="7: DeclStmt \n n$1=*&x:int [line 13]\n *&a:int =n$1 [line 13]\n REMOVE_TEMPS(n$1); [line 13]\n " shape="box"]
|
||||
|
||||
|
||||
7 -> 5 ;
|
||||
7 -> 6 ;
|
||||
6 [label="6: Prune (false branch) \n n$0=*&a:int [line 13]\n PRUNE((n$0 == 0), false); [line 13]\n REMOVE_TEMPS(n$0); [line 13]\n " shape="invhouse"]
|
||||
|
||||
|
||||
6 -> 3 ;
|
||||
5 [label="5: Prune (true branch) \n n$0=*&a:int [line 13]\n PRUNE((n$0 != 0), true); [line 13]\n REMOVE_TEMPS(n$0); [line 13]\n " shape="invhouse"]
|
||||
|
||||
|
||||
5 -> 9 ;
|
||||
4 [label="4: + \n " ]
|
||||
|
||||
|
||||
4 -> 7 ;
|
||||
3 [label="3: Return Stmt \n NULLIFY(&a,false); [line 17]\n NULLIFY(&result,false); [line 17]\n NULLIFY(&x,false); [line 17]\n *&return:int =0 [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"]
|
||||
|
||||
|
||||
3 -> 2 ;
|
||||
2 [label="2: Exit simple_assignment \n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 [label="1: Start simple_assignment\nFormals: \nLocals: a:int result:int x:int \n DECLARE_LOCALS(&return,&a,&result,&x); [line 10]\n NULLIFY(&a,false); [line 10]\n NULLIFY(&result,false); [line 10]\n NULLIFY(&x,false); [line 10]\n " color=yellow style=filled]
|
||||
|
||||
|
||||
1 -> 11 ;
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package endtoend.cpp;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static utils.matchers.ResultContainsErrorInMethod.contains;
|
||||
import static utils.matchers.ResultContainsNoErrorInMethod.doesNotContain;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import utils.DebuggableTemporaryFolder;
|
||||
import utils.InferException;
|
||||
import utils.InferResults;
|
||||
import utils.InferRunner;
|
||||
|
||||
public class NestedCPPOperatorsTest {
|
||||
|
||||
public static final String FILE =
|
||||
"infer/tests/codetoanalyze/cpp/frontend/nestedoperators/var_decl_inside_if.cpp";
|
||||
|
||||
private static ImmutableList<String> inferCmd;
|
||||
|
||||
public static final String DIVIDE_BY_ZERO = "DIVIDE_BY_ZERO";
|
||||
public static final String NULL_DEREFERENCE = "NULL_DEREFERENCE";
|
||||
|
||||
@ClassRule
|
||||
public static DebuggableTemporaryFolder folder =
|
||||
new DebuggableTemporaryFolder();
|
||||
|
||||
@BeforeClass
|
||||
public static void runInfer() throws InterruptedException, IOException {
|
||||
inferCmd = InferRunner.createCPPInferCommand(folder, FILE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInferRunsOnDiv0MethodsErrorIsFound()
|
||||
throws InterruptedException, IOException, InferException {
|
||||
InferResults inferResults = InferRunner.runInferCPP(inferCmd);
|
||||
String[] proceduresWithDiv0 = {
|
||||
"simple_init_div0",
|
||||
"simple_inif_elseif_div0",
|
||||
"function_call_init_div0",
|
||||
"conditional_init_div0",
|
||||
"reference_init_div0",
|
||||
};
|
||||
for (String procedure : proceduresWithDiv0) {
|
||||
assertThat(
|
||||
"Results should contain the expected divide by zero",
|
||||
inferResults,
|
||||
contains(
|
||||
DIVIDE_BY_ZERO,
|
||||
FILE,
|
||||
procedure
|
||||
)
|
||||
);
|
||||
}
|
||||
/* null dereference */
|
||||
assertThat(
|
||||
"Results should contain the expected null dereference",
|
||||
inferResults,
|
||||
contains(
|
||||
NULL_DEREFERENCE,
|
||||
FILE,
|
||||
"simple_init_null_deref"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package frontend.cpp;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import utils.DebuggableTemporaryFolder;
|
||||
import utils.InferException;
|
||||
import utils.ClangFrontendUtils;
|
||||
|
||||
public class NestedCPPOperatorsTest {
|
||||
|
||||
String nestedOperatorsBasePath = "infer/tests/codetoanalyze/cpp/frontend/nestedoperators/";
|
||||
|
||||
@Rule
|
||||
public DebuggableTemporaryFolder folder = new DebuggableTemporaryFolder();
|
||||
|
||||
void frontendTest(String fileRelative) throws InterruptedException, IOException, InferException {
|
||||
ClangFrontendUtils.createAndCompareCppDotFiles(folder, nestedOperatorsBasePath + fileRelative);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testVarDeclInsideIfDotFilesMatch()
|
||||
throws InterruptedException, IOException, InferException {
|
||||
frontendTest("var_decl_inside_if.cpp");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVarDeclInsideWhileDotFilesMatch()
|
||||
throws InterruptedException, IOException, InferException {
|
||||
frontendTest("var_decl_inside_while.cpp");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVarDeclInsideForDotFilesMatch()
|
||||
throws InterruptedException, IOException, InferException {
|
||||
frontendTest("var_decl_inside_for.cpp");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue