diff options
Diffstat (limited to 'clang/test/Analysis/track-control-dependency-conditions.cpp')
| -rw-r--r-- | clang/test/Analysis/track-control-dependency-conditions.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/clang/test/Analysis/track-control-dependency-conditions.cpp b/clang/test/Analysis/track-control-dependency-conditions.cpp new file mode 100644 index 00000000000..1f64eeefede --- /dev/null +++ b/clang/test/Analysis/track-control-dependency-conditions.cpp @@ -0,0 +1,285 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -verify=expected,tracking \ +// RUN: -analyzer-config track-conditions=true \ +// RUN: -analyzer-output=text \ +// RUN: -analyzer-checker=core +// +// RUN: %clang_analyze_cc1 %s -verify \ +// RUN: -analyzer-output=text \ +// RUN: -analyzer-checker=core + +namespace example_1 { +int flag; +bool coin(); + +void foo() { + flag = coin(); // tracking-note{{Value assigned to 'flag'}} +} + +void test() { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + flag = 1; + + foo(); // TODO: Add nodes here about flag's value being invalidated. + if (flag) // expected-note {{Assuming 'flag' is 0}} + // expected-note@-1{{Taking false branch}} + x = new int; + + foo(); // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + + if (flag) // expected-note {{Assuming 'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace example_1 + +namespace example_2 { +int flag; +bool coin(); + +void foo() { + flag = coin(); // tracking-note{{Value assigned to 'flag'}} +} + +void test() { + int *x = 0; + flag = 1; + + foo(); + if (flag) // expected-note {{Assuming 'flag' is 0}} + // expected-note@-1{{Taking false branch}} + x = new int; + + x = 0; // expected-note{{Null pointer value stored to 'x'}} + + foo(); // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + + if (flag) // expected-note {{Assuming 'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace example_2 + +namespace global_variable_invalidation { +int flag; +bool coin(); + +void foo() { + // coin() could write bar, do it's invalidated. + flag = coin(); // tracking-note{{Value assigned to 'flag'}} + // tracking-note@-1{{Value assigned to 'bar'}} +} + +int bar; + +void test() { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + flag = 1; + + foo(); // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + + if (bar) // expected-note {{Assuming 'bar' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + if (flag) // expected-note {{Assuming 'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace global_variable_invalidation + +namespace variable_declaration_in_condition { +bool coin(); + +bool foo() { + return coin(); // tracking-note{{Returning value}} +} + +int bar; + +void test() { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + + if (int flag = foo()) // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + // tracking-note@-2{{'flag' initialized here}} + + // expected-note@-4{{Assuming 'flag' is not equal to 0}} + // expected-note@-5{{Taking true branch}} + + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace variable_declaration_in_condition + +namespace conversion_to_bool { +bool coin(); + +struct ConvertsToBool { + operator bool() const { return coin(); } // tracking-note{{Returning value}} +}; + +void test() { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + + if (ConvertsToBool()) + // tracking-note@-1 {{Calling 'ConvertsToBool::operator bool'}} + // tracking-note@-2{{Returning from 'ConvertsToBool::operator bool'}} + + // expected-note@-4{{Assuming the condition is true}} + // expected-note@-5{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +} // end of namespace variable_declaration_in_condition + +namespace unimportant_returning_value_note { +bool coin(); + +bool flipCoin() { return coin(); } // tracking-note{{Returning value}} + +void i(int *ptr) { + if (ptr) // expected-note{{Assuming 'ptr' is null}} + // expected-note@-1{{Taking false branch}} + ; + if (!flipCoin()) + // tracking-note@-1{{Calling 'flipCoin'}} + // tracking-note@-2{{Returning from 'flipCoin'}} + // expected-note@-3{{Assuming the condition is true}} + // expected-note@-4{{Taking true branch}} + *ptr = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace unimportant_returning_value_note + +namespace important_returning_value_note { +bool coin(); + +bool flipCoin() { + if (coin()) // tracking-note{{Assuming the condition is false}} + // tracking-note@-1{{Taking false branch}} + return true; + return coin(); // tracking-note{{Returning value}} +} + +void i(int *ptr) { + if (ptr) // expected-note{{Assuming 'ptr' is null}} + // expected-note@-1{{Taking false branch}} + ; + if (!flipCoin()) + // tracking-note@-1{{Calling 'flipCoin'}} + // tracking-note@-2{{Returning from 'flipCoin'}} + // expected-note@-3{{Assuming the condition is true}} + // expected-note@-4{{Taking true branch}} + *ptr = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace important_returning_value_note + +namespace tracked_condition_is_only_initialized { +int getInt(); + +void f() { + int flag = getInt(); // tracking-note{{'flag' initialized here}} + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + if (flag) // expected-note{{Assuming 'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace tracked_condition_is_only_initialized + +namespace tracked_condition_written_in_same_stackframe { +int flag; +int getInt(); + +void f(int y) { + y = 1; // tracking-note{{The value 1 is assigned to 'y'}} + flag = y; // tracking-note{{The value 1 is assigned to 'flag'}} + + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + if (flag) // expected-note{{'flag' is 1}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace tracked_condition_written_in_same_stackframe + +namespace tracked_condition_written_in_nested_stackframe { +int flag; +int getInt(); + +void foo() { + int y; + y = 1; // tracking-note{{The value 1 is assigned to 'y'}} + flag = y; // tracking-note{{The value 1 is assigned to 'flag'}} + +} + +void f(int y) { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + + foo(); // tracking-note{{Calling 'foo'}} + // tracking-note@-1{{Returning from 'foo'}} + + if (flag) // expected-note{{'flag' is 1}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} +} // end of namespace tracked_condition_written_in_nested_stackframe + +namespace collapse_point_not_in_condition { + +[[noreturn]] void halt(); + +void assert(int b) { + if (!b) // tracking-note{{Assuming 'b' is not equal to 0}} + // tracking-note@-1{{Taking false branch}} + halt(); +} + +void f(int flag) { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + + assert(flag); // tracking-note{{Calling 'assert'}} + // tracking-note@-1{{Returning from 'assert'}} + + if (flag) // expected-note{{'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +} // end of namespace collapse_point_not_in_condition + +namespace unimportant_write_before_collapse_point { + +[[noreturn]] void halt(); + +void assert(int b) { + if (!b) // tracking-note{{Assuming 'b' is not equal to 0}} + // tracking-note@-1{{Taking false branch}} + halt(); +} +int getInt(); + +void f(int flag) { + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + + flag = getInt(); // tracking-note{{Value assigned to 'flag'}} + assert(flag); // tracking-note{{Calling 'assert'}} + // tracking-note@-1{{Returning from 'assert'}} + + if (flag) // expected-note{{'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +} // end of namespace unimportant_write_before_collapse_point |

