diff options
| author | Kristof Umann <dkszelethus@gmail.com> | 2019-08-13 23:48:10 +0000 |
|---|---|---|
| committer | Kristof Umann <dkszelethus@gmail.com> | 2019-08-13 23:48:10 +0000 |
| commit | 0df9c8c57802b0b1c75380c904b3cce0b902e2c5 (patch) | |
| tree | 779f5bb4d9e19c1f7c5f9f40e981fa9cb631a2a8 /clang/test/Analysis | |
| parent | 3cb3aa2ee807cc93a1659b3bfa0e23292b4fee78 (diff) | |
| download | bcm5719-llvm-0df9c8c57802b0b1c75380c904b3cce0b902e2c5.tar.gz bcm5719-llvm-0df9c8c57802b0b1c75380c904b3cce0b902e2c5.zip | |
[analyzer] Track the right hand side of the last store regardless of its value
Summary:
The following code snippet taken from D64271#1572188 has an issue: namely,
because `flag`'s value isn't undef or a concrete int, it isn't being tracked.
int flag;
bool coin();
void foo() {
flag = coin();
}
void test() {
int *x = 0;
int local_flag;
flag = 1;
foo();
local_flag = flag;
if (local_flag)
x = new int;
foo();
local_flag = flag;
if (local_flag)
*x = 5;
}
This, in my opinion, makes no sense, other values may be interesting too.
Originally added by rC185608.
Differential Revision: https://reviews.llvm.org/D64287
llvm-svn: 368773
Diffstat (limited to 'clang/test/Analysis')
| -rw-r--r-- | clang/test/Analysis/track-control-dependency-conditions.cpp | 24 | ||||
| -rw-r--r-- | clang/test/Analysis/uninit-const.c | 27 | ||||
| -rw-r--r-- | clang/test/Analysis/uninit-const.cpp | 6 |
3 files changed, 42 insertions, 15 deletions
diff --git a/clang/test/Analysis/track-control-dependency-conditions.cpp b/clang/test/Analysis/track-control-dependency-conditions.cpp index 93a5efb39db..644eb6296fe 100644 --- a/clang/test/Analysis/track-control-dependency-conditions.cpp +++ b/clang/test/Analysis/track-control-dependency-conditions.cpp @@ -366,6 +366,30 @@ void f(int y) { } } // end of namespace tracked_condition_written_in_nested_stackframe +namespace condition_written_in_nested_stackframe_before_assignment { +int flag = 0; +int getInt(); + +void foo() { + flag = getInt(); // tracking-note{{Value assigned to 'flag'}} +} + +void f() { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + int y = 0; + + foo(); // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + y = flag; // tracking-note{{Value assigned to 'y'}} + + if (y) // expected-note{{Assuming 'y' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'y'}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace condition_written_in_nested_stackframe_before_assignment + namespace collapse_point_not_in_condition { [[noreturn]] void halt(); diff --git a/clang/test/Analysis/uninit-const.c b/clang/test/Analysis/uninit-const.c index 407c28a5e8b..ec29c236069 100644 --- a/clang/test/Analysis/uninit-const.c +++ b/clang/test/Analysis/uninit-const.c @@ -24,15 +24,15 @@ void doStuff_constStaticSizedArray(const int a[static 10]) {} void doStuff_variadic(const int *u, ...){}; void f_1(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_1_1(void) { - int t; - int* tp1 = &t; + int t; // expected-note {{'t' declared without an initial value}} + int *tp1 = &t; // expected-note {{'tp1' initialized here}} int* tp2 = tp1; // expected-note {{'tp2' initialized here}} doStuff_pointerToConstInt(tp2); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -40,12 +40,15 @@ void f_1_1(void) { int *f_2_sub(int *p) { - return p; + return p; // expected-note {{Returning pointer (loaded from 'p')}} } void f_2(void) { - int t; - int* p = f_2_sub(&t); + int t; // expected-note {{'t' declared without an initial value}} + int *p = f_2_sub(&t); // expected-note {{Passing value via 1st parameter 'p'}} + // expected-note@-1{{Calling 'f_2_sub'}} + // expected-note@-2{{Returning from 'f_2_sub'}} + // expected-note@-3{{'p' initialized here}} int* tp = p; // expected-note {{'tp' initialized here}} doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -62,7 +65,7 @@ void f_4(void) { } void f_5(void) { - int ta[5]; + int ta[5]; // expected-note {{'ta' initialized here}} int* tp = ta; // expected-note {{'tp' initialized here}} doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -99,7 +102,7 @@ void f_8(void) { } void f_9(void) { - int a[6]; + int a[6]; // expected-note {{'a' initialized here}} int const *ptau = a; // expected-note {{'ptau' initialized here}} doStuff_arrayOfConstInt(ptau); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} @@ -173,7 +176,7 @@ int f_malloc_2(void) { // uninit pointer, uninit val void f_variadic_unp_unv(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int v; int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_variadic(tp,v); // expected-warning {{1st function call argument is a pointer to uninitialized value}} @@ -181,7 +184,7 @@ void f_variadic_unp_unv(void) { } // uninit pointer, init val void f_variadic_unp_inv(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int v = 3; int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_variadic(tp,v); // expected-warning {{1st function call argument is a pointer to uninitialized value}} @@ -216,7 +219,7 @@ void f_variadic_inp_inp(void) { //uninit pointer, init pointer void f_variadic_unp_inp(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int u=3; int *vp = &u ; int *tp = &t; // expected-note {{'tp' initialized here}} @@ -235,7 +238,7 @@ void f_variadic_inp_unp(void) { //uninit pointer, uninit pointer void f_variadic_unp_unp(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int u; int *vp = &u ; int *tp = &t; // expected-note {{'tp' initialized here}} diff --git a/clang/test/Analysis/uninit-const.cpp b/clang/test/Analysis/uninit-const.cpp index b6430307dc5..3b7089cbcac 100644 --- a/clang/test/Analysis/uninit-const.cpp +++ b/clang/test/Analysis/uninit-const.cpp @@ -66,8 +66,8 @@ void f6_1(void) { void f6_2(void) { int t; //expected-note {{'t' declared without an initial value}} - int &p = t; - int &s = p; + int &p = t; //expected-note {{'p' initialized here}} + int &s = p; //expected-note {{'s' initialized here}} int &q = s; //expected-note {{'q' initialized here}} doStuff6(q); //expected-warning {{1st function call argument is an uninitialized value}} //expected-note@-1 {{1st function call argument is an uninitialized value}} @@ -96,7 +96,7 @@ void f6(void) { void f5(void) { - int t; + int t; // expected-note {{'t' declared without an initial value}} int* tp = &t; // expected-note {{'tp' initialized here}} doStuff_uninit(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} |

