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