Added some false positive checking to UnreachableCodeChecker
- Allowed reporting of dead macros
- Added path walking function to search for false positives in conditional statements
- Updated some affected tests
- Added some false positive test cases

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109561 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/additive-folding.c b/test/Analysis/additive-folding.c
index 6e81fcf..e4a5651 100644
--- a/test/Analysis/additive-folding.c
+++ b/test/Analysis/additive-folding.c
@@ -61,7 +61,7 @@
   if (a+1 != 0)
     return; // no-warning
   if (a-1 != UINT_MAX-1)
-    return; // expected-warning{{never executed}}
+    return; // no-warning
   free(b);
 }
 
@@ -72,7 +72,7 @@
   if (a+1 == 0)
     return; // no-warning
   if (a-1 == UINT_MAX-1)
-    return; // expected-warning{{never executed}}
+    return; // no-warning
   free(b);
 }
 
@@ -177,7 +177,7 @@
 void tautologyGT (unsigned a) {
   char* b = malloc(1);
   if (a > UINT_MAX)
-    return; // expected-warning{{never executed}}
+    return; // no-warning
   free(b);
 }
 
diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c
index 3a5dfab..418b323 100644
--- a/test/Analysis/bstring.c
+++ b/test/Analysis/bstring.c
@@ -53,7 +53,7 @@
   memcpy(dst, src, 4); // no-warning
 
   if (memcpy(dst, src, 4) != dst) {
-    (void)*(char*)0; // expected-warning{{never executed}}
+    (void)*(char*)0; // no-warning
   }
 }
 
@@ -155,7 +155,7 @@
   memmove(dst, src, 4); // no-warning
 
   if (memmove(dst, src, 4) != dst) {
-    (void)*(char*)0; // expected-warning{{never executed}}
+    (void)*(char*)0; // no-warning
   }
 }
 
@@ -217,7 +217,7 @@
   char a[] = {1, 2, 3, 4};
 
   if (memcmp(a, a, 4))
-    (void)*(char*)0; // expected-warning{{never executed}}
+    (void)*(char*)0; // no-warning
 }
 
 void memcmp4 (char *input) {
@@ -231,11 +231,11 @@
   char a[] = {1, 2, 3, 4};
 
   if (memcmp(a, 0, 0)) // no-warning
-    (void)*(char*)0;   // expected-warning{{never executed}}
+    (void)*(char*)0;   // no-warning
   if (memcmp(0, a, 0)) // no-warning
-    (void)*(char*)0;   // expected-warning{{never executed}}
+    (void)*(char*)0;   // no-warning
   if (memcmp(a, input, 0)) // no-warning
-    (void)*(char*)0;   // expected-warning{{never executed}}
+    (void)*(char*)0;   // no-warning
 }
 
 void memcmp6 (char *a, char *b, size_t n) {
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
index b1ca3ee..85e47c8 100644
--- a/test/Analysis/constant-folding.c
+++ b/test/Analysis/constant-folding.c
@@ -9,51 +9,51 @@
   // Sema can already catch the simple comparison a==a,
   // since that's usually a logic error (and not path-dependent).
   int b = a;
-  if (!(b==a)) WARN;
-  if (!(b>=a)) WARN;
-  if (!(b<=a)) WARN;
-  if (b!=a) WARN;
-  if (b>a) WARN;
-  if (b<a) WARN;
+  if (!(b==a)) WARN; // expected-warning{{never executed}}
+  if (!(b>=a)) WARN; // expected-warning{{never executed}}
+  if (!(b<=a)) WARN; // expected-warning{{never executed}}
+  if (b!=a) WARN;    // expected-warning{{never executed}}
+  if (b>a) WARN;     // expected-warning{{never executed}}
+  if (b<a) WARN;     // expected-warning{{never executed}}
 }
 
 void testSelfOperations (int a) {
-  if ((a|a) != a) WARN; // expected-warning{{Both operands to '|' always have the same value}}
-  if ((a&a) != a) WARN; // expected-warning{{Both operands to '&' always have the same value}}
-  if ((a^a) != 0) WARN; // expected-warning{{Both operands to '^' always have the same value}}
-  if ((a-a) != 0) WARN; // expected-warning{{Both operands to '-' always have the same value}}
+  if ((a|a) != a) WARN; // expected-warning{{Both operands to '|' always have the same value}} expected-warning{{never executed}}
+  if ((a&a) != a) WARN; // expected-warning{{Both operands to '&' always have the same value}} expected-warning{{never executed}}
+  if ((a^a) != 0) WARN; // expected-warning{{Both operands to '^' always have the same value}} expected-warning{{never executed}}
+  if ((a-a) != 0) WARN; // expected-warning{{Both operands to '-' always have the same value}} expected-warning{{never executed}}
 }
 
 void testIdempotent (int a) {
-  if ((a*1) != a) WARN;
-  if ((a/1) != a) WARN;
-  if ((a+0) != a) WARN;
-  if ((a-0) != a) WARN;
-  if ((a<<0) != a) WARN;
-  if ((a>>0) != a) WARN;
-  if ((a^0) != a) WARN;
-  if ((a&(~0)) != a) WARN;
-  if ((a|0) != a) WARN;
+  if ((a*1) != a) WARN;    // expected-warning{{never executed}}
+  if ((a/1) != a) WARN;    // expected-warning{{never executed}}
+  if ((a+0) != a) WARN;    // expected-warning{{never executed}}
+  if ((a-0) != a) WARN;    // expected-warning{{never executed}}
+  if ((a<<0) != a) WARN;   // expected-warning{{never executed}}
+  if ((a>>0) != a) WARN;   // expected-warning{{never executed}}
+  if ((a^0) != a) WARN;    // expected-warning{{never executed}}
+  if ((a&(~0)) != a) WARN; // expected-warning{{never executed}}
+  if ((a|0) != a) WARN;    // expected-warning{{never executed}}
 }
 
 void testReductionToConstant (int a) {
-  if ((a*0) != 0) WARN;
-  if ((a&0) != 0) WARN;
-  if ((a|(~0)) != (~0)) WARN;
+  if ((a*0) != 0) WARN; // expected-warning{{never executed}}
+  if ((a&0) != 0) WARN; // expected-warning{{never executed}}
+  if ((a|(~0)) != (~0)) WARN; // expected-warning{{never executed}}
 }
 
 void testSymmetricIntSymOperations (int a) {
-  if ((2+a) != (a+2)) WARN;
-  if ((2*a) != (a*2)) WARN;
-  if ((2&a) != (a&2)) WARN;
-  if ((2^a) != (a^2)) WARN;
-  if ((2|a) != (a|2)) WARN;
+  if ((2+a) != (a+2)) WARN; // expected-warning{{never executed}}
+  if ((2*a) != (a*2)) WARN; // expected-warning{{never executed}}
+  if ((2&a) != (a&2)) WARN; // expected-warning{{never executed}}
+  if ((2^a) != (a^2)) WARN; // expected-warning{{never executed}}
+  if ((2|a) != (a|2)) WARN; // expected-warning{{never executed}}
 }
 
 void testAsymmetricIntSymOperations (int a) {
-  if (((~0) >> a) != (~0)) WARN;
-  if ((0 >> a) != 0) WARN;
-  if ((0 << a) != 0) WARN;
+  if (((~0) >> a) != (~0)) WARN; // expected-warning{{never executed}}
+  if ((0 >> a) != 0) WARN; // expected-warning{{never executed}}
+  if ((0 << a) != 0) WARN; // expected-warning{{never executed}}
 
   // Unsigned right shift shifts in zeroes.
   if ((((unsigned)(~0)) >> ((unsigned) a)) != ((unsigned)(~0)))
@@ -62,11 +62,11 @@
 
 void testLocations (char *a) {
   char *b = a;
-  if (!(b==a)) WARN;
-  if (!(b>=a)) WARN;
-  if (!(b<=a)) WARN;
-  if (b!=a) WARN;
-  if (b>a) WARN;
-  if (b<a) WARN;
-  if (b-a) WARN; // expected-warning{{Both operands to '-' always have the same value}}
+  if (!(b==a)) WARN; // expected-warning{{never executed}}
+  if (!(b>=a)) WARN; // expected-warning{{never executed}}
+  if (!(b<=a)) WARN; // expected-warning{{never executed}}
+  if (b!=a) WARN; // expected-warning{{never executed}}
+  if (b>a) WARN; // expected-warning{{never executed}}
+  if (b<a) WARN; // expected-warning{{never executed}}
+  if (b-a) WARN; // expected-warning{{Both operands to '-' always have the same value}} expected-warning{{never executed}}
 }
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index b4d21cd..f24d71c 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -35,13 +35,13 @@
 
 void strlen_constant0() {
   if (strlen("123") != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+    (void)*(char*)0;
 }
 
 void strlen_constant1() {
   const char *a = "123";
   if (strlen(a) != 3)
-    (void)*(char*)0; // expected-warning{{never executed}}
+    (void)*(char*)0;
 }
 
 void strlen_constant2(char x) {
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
index e7e1d0b..00987dd 100644
--- a/test/Analysis/unreachable-code-path.c
+++ b/test/Analysis/unreachable-code-path.c
@@ -2,6 +2,8 @@
 
 extern void foo(int a);
 
+// The first few tests are non-path specific - we should be able to find them
+
 void test(unsigned a) {
   switch (a) {
     a += 5; // expected-warning{{never executed}}
@@ -23,7 +25,16 @@
   goto help;
 }
 
-void test3() {
+void test3(unsigned a) {
+  while(1);
+  if (a > 5) { // expected-warning{{never executed}}
+    return;
+  }
+}
+
+// These next tests are path-sensitive
+
+void test4() {
   int a = 5;
 
   while (a > 1)
@@ -36,13 +47,6 @@
   foo(a);
 }
 
-void test4(unsigned a) {
-  while(1);
-  if (a > 5) { // expected-warning{{never executed}}
-    return;
-  }
-}
-
 extern void bar(char c);
 
 void test5(const char *c) {
@@ -53,9 +57,34 @@
   }
 }
 
+// These next tests are false positives and should not generate warnings
+
 void test6(const char *c) {
   if (c) return;
   if (!c) return;
   __builtin_unreachable(); // no-warning
 }
 
+// Compile-time constant false positives
+#define CONSTANT 0
+enum test_enum { Off, On };
+void test7() {
+  if (CONSTANT)
+    return; // no-warning
+
+  if (sizeof(int))
+    return; // no-warning
+
+  if (Off)
+    return; // no-warning
+}
+
+void test8() {
+  static unsigned a = 0;
+
+  if (a)
+    a = 123; // no-warning
+
+  a = 5;
+}
+