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