Improved IdempotentOperationChecker false positives and false negatives.
- Unfinished analysis may still report valid warnings if the path was completely analyzed
- New 'CanVary' heuristic to recursively determine if a subexpression has a varying element
- Updated test cases, including one known bug
- Exposed GRCoreEngine through GRExprEngine
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110970 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index cc8a3f5..3cd0612 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -150,7 +150,7 @@
int f16(int x) {
x = x * 2;
- x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}}
+ x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}} expected-warning{{The left operand to '*' is always 1}}
? 5 : 8;
return x;
}
diff --git a/test/Analysis/idempotent-operations.c b/test/Analysis/idempotent-operations.c
index 2543b1a..23401e8 100644
--- a/test/Analysis/idempotent-operations.c
+++ b/test/Analysis/idempotent-operations.c
@@ -53,20 +53,33 @@
}
void floats(float x) {
- test_f(x * 1.0); // no-warning
+ test_f(x * 1.0); // no-warning
test_f(x * 1.0F); // no-warning
}
-// Ensure that we don't report false poitives on complex loops
+// Ensure that we don't report false poitives in complex loops
void bailout() {
- int unused, result = 4;
- int numbers[5] = { 0, 32, 'x', 128, 255 };
+ int unused = 0, result = 4;
+ result = result; // expected-warning {{Assigned value is always the same as the existing value}}
- for (int bg = 0; bg < 5; bg ++) {
- result += numbers[bg]; // no-warning
+ for (unsigned bg = 0; bg < 1024; bg ++) {
+ result = bg * result; // no-warning
for (int i = 0; i < 256; i++) {
- unused = i;
+ unused *= i; // no-warning
}
}
}
+
+// False positive tests
+
+unsigned false1() {
+ return (5 - 2 - 3); // no-warning
+}
+
+enum testenum { enum1 = 0, enum2 };
+unsigned false2() {
+ return enum1; // no-warning
+}
+
+extern unsigned foo();
diff --git a/test/Analysis/null-deref-ps-temp.c b/test/Analysis/null-deref-ps-temp.c
new file mode 100644
index 0000000..90b6ed3
--- /dev/null
+++ b/test/Analysis/null-deref-ps-temp.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-no-purge-dead -verify %s -Wreturn-type
+
+// This is a temporary file to isolate a test case that would cause a failure
+// only some of the time in null-deref-ps.c. The idempotent operations checker
+// has revealed a bug on line 18 ('=' instead of '==') when the
+// -analyzer-no-purge-dead flag is passed to cc1. Some fundamental design
+// changes are needed to make this work without the -analyzer-no-purge-dead flag
+// and this test will be integrated back into the main file when this happens.
+
+typedef unsigned uintptr_t;
+
+int f4_b() {
+ short array[2];
+ uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion}}
+ short *p = x; // expected-warning{{incompatible integer to pointer conversion}}
+
+ // The following branch should be infeasible.
+ if (!(p = &array[0])) { // expected-warning{{Assigned value is always the same as the existing value}}
+ p = 0;
+ *p = 1; // no-warning
+ }
+
+ if (p) {
+ *p = 5; // no-warning
+ p = 0;
+ }
+ else return; // expected-warning {{non-void function 'f4_b' should return a value}}
+
+ *p += 10; // expected-warning{{Dereference of null pointer}}
+ return 0;
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 9be73a8..1ae94c7 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -60,27 +60,7 @@
return *q; // expected-warning{{Dereference of null pointer (loaded from variable 'q')}}
}
-int f4_b() {
- short array[2];
- uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion}}
- short *p = x; // expected-warning{{incompatible integer to pointer conversion}}
-
- // The following branch should be infeasible.
- if (!(p = &array[0])) {
- p = 0;
- *p = 1; // no-warning
- }
-
- if (p) {
- *p = 5; // no-warning
- p = 0;
- }
- else return; // expected-warning {{non-void function 'f4_b' should return a value}}
-
- *p += 10; // expected-warning{{Dereference of null pointer}}
- return 0;
-}
-
+// Placeholder for f4_b, temporarily moved to null-deref-ps-temp.c
int f5() {
@@ -280,7 +260,7 @@
// Test handling of translating between integer "pointers" and back.
void f13() {
int *x = 0;
- if (((((int) x) << 2) + 1) >> 1) *x = 1; // expected-warning{{he left operand to '<<' is always 0}}
+ if (((((int) x) << 2) + 1) >> 1) *x = 1; // expected-warning{{The left operand to '<<' is always 0}} expected-warning{{The left operand to '+' is always 0}}
}
// PR 4759 - Attribute non-null checking by the analyzer was not correctly