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;
+}
+