summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/track-control-dependency-conditions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/track-control-dependency-conditions.cpp')
-rw-r--r--clang/test/Analysis/track-control-dependency-conditions.cpp285
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
OpenPOWER on IntegriCloud