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