Add rudimentary path-sensitivity to UnintializedValuesV2
analysis for short-circuited operations. For branch written like "if (x && y)",
we maintain two sets of dataflow values for the outgoing
branches. This suppresses some common false positives
for -Wuninitialized-experimental.
This change introduces some assertion failures
when running on the LLVM codebase. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123923 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c
index 58bcbb0..7ac225f 100644
--- a/test/Sema/uninit-variables.c
+++ b/test/Sema/uninit-variables.c
@@ -110,4 +110,63 @@
*x = 1; // expected-warning{{use of uninitialized variable 'x'}}
*x = 1; // no-warning
}
-
+
+int test18(int x, int y) {
+ int z;
+ if (x && y && (z = 1)) {
+ return z; // no-warning
+ }
+ return 0;
+}
+
+int test19_aux1();
+int test19_aux2();
+int test19_aux3(int *x);
+int test19() {
+ int z;
+ if (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))
+ return z; // no-warning
+ return 0;
+}
+
+int test20() {
+ int z;
+ if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z))
+ return z; // expected-warning{{use of uninitialized variable 'z'}}
+ return 0;
+}
+
+int test21(int x, int y) {
+ int z;
+ if ((x && y) || test19_aux3(&z) || test19_aux2())
+ return z; // expected-warning{{use of uninitialized variable 'z'}}
+ return 0;
+}
+
+int test22() {
+ int z;
+ while (test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z))
+ return z; // no-warning
+ return 0;
+}
+
+int test23() {
+ int z;
+ for ( ; test19_aux1() + test19_aux2() && test19_aux1() && test19_aux3(&z) ; )
+ return z; // no-warning
+ return 0;
+}
+
+// The basic uninitialized value analysis doesn't have enough path-sensitivity
+// to catch initializations relying on control-dependencies spanning multiple
+// conditionals. This possibly can be handled by making the CFG itself
+// represent such control-dependencies, but it is a niche case.
+int test24(int flag) {
+ unsigned val;
+ if (flag)
+ val = 1;
+ if (!flag)
+ val = 1;
+ return val; // expected-warning{{use of uninitialized variable 'val'}}
+}
+