Added psuedo-constant analysis and integrated it into the false positive reduction stage in IdempotentOperationChecker.
- Renamed IdempotentOperationChecker::isConstant to isConstantOrPseudoConstant to better reflect the function
- Changed IdempotentOperationChecker::PreVisitBinaryOperator to only run 'CanVary' once on undefined assumptions
- Created new PsuedoConstantAnalysis class and added it to AnalysisContext
- Changed IdempotentOperationChecker to exploit the new analysis
- Updated tests with psuedo-constants
- Added check to IdempotentOperationChecker to see if a Decl is const qualified

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111426 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
index 85e47c8..9191a9e0 100644
--- a/test/Analysis/constant-folding.c
+++ b/test/Analysis/constant-folding.c
@@ -18,10 +18,10 @@
 }
 
 void testSelfOperations (int a) {
-  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}}
+  if ((a|a) != a) WARN; // expected-warning{{never executed}}
+  if ((a&a) != a) WARN; // expected-warning{{never executed}}
+  if ((a^a) != 0) WARN; // expected-warning{{never executed}}
+  if ((a-a) != 0) WARN; // expected-warning{{never executed}}
 }
 
 void testIdempotent (int a) {
@@ -68,5 +68,5 @@
   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}}
+  if (b-a) WARN; // expected-warning{{never executed}}
 }
diff --git a/test/Analysis/idempotent-operations.c b/test/Analysis/idempotent-operations.c
index a54a3aa..abf6710 100644
--- a/test/Analysis/idempotent-operations.c
+++ b/test/Analysis/idempotent-operations.c
@@ -5,7 +5,7 @@
 extern void test(int i);
 extern void test_f(float f);
 
-void basic() {
+unsigned basic() {
   int x = 10, zero = 0, one = 1;
 
   // x op x
@@ -50,6 +50,13 @@
   test(zero ^ x);  // expected-warning {{The left operand to '^' is always 0}}
   test(zero << x); // expected-warning {{The left operand to '<<' is always 0}}
   test(zero >> x); // expected-warning {{The left operand to '>>' is always 0}}
+
+  // Overwrite the values so these aren't marked as psuedoconstants
+  x = 1;
+  zero = 2;
+  one = 3;
+
+  return x + zero + one;
 }
 
 void floats(float x) {
@@ -84,4 +91,23 @@
   return enum1 + a; // no-warning
 }
 
-extern unsigned foo();
+// Self assignments of parameters are common false positives
+unsigned false3(int param) {
+  param = param; // no-warning
+
+  unsigned nonparam = 5;
+
+  nonparam = nonparam; // expected-warning{{Assigned value is always the same as the existing value}}
+
+  return nonparam;
+}
+
+// Psuedo-constants (vars only read) and constants should not be reported
+unsigned false4() {
+  // Trivial constant
+  const int height = 1; // no-warning
+  // Psuedo-constant (never changes after decl)
+  int width = height; // no-warning
+
+  return width * 10; // no-warning
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 1ae94c7..356e2b4 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -260,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{{The left operand to '<<' is always 0}} expected-warning{{The left operand to '+' is always 0}}
+  if (((((int) x) << 2) + 1) >> 1) *x = 1;
 }
 
 // PR 4759 - Attribute non-null checking by the analyzer was not correctly