diff options
author | Tom Care <tom.care@uqconnect.edu.au> | 2010-08-24 21:09:07 +0000 |
---|---|---|
committer | Tom Care <tom.care@uqconnect.edu.au> | 2010-08-24 21:09:07 +0000 |
commit | ef52bcb606c73950139a775af61495f63fbc3603 (patch) | |
tree | aafe54f1a52e53ede92f8a8b945551bec366c92c /lib/Checker/IdempotentOperationChecker.cpp | |
parent | 120d63cd4465230c2cd56508c7cd8e0ad00848e7 (diff) |
Improvements to IdempotentOperationChecker and its use of PseudoConstantAnalysis
- Added wasReferenced function to PseudoConstantAnalysis to determine if a variable was ever referenced in a function (outside of a self-assignment)
- BlockDeclRefExpr referenced variables are now explicitly added to the non-constant list
- Remove unnecessary ignore of implicit casts
- Generalized parameter self-assign detection to detect deliberate self-assigns of variables to avoid unused variable warnings
- Updated test cases with deliberate self-assignments
- Fixed bug with C++ references and pseudoconstants
- Added test case for C++ references and pseudoconstants
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111965 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/IdempotentOperationChecker.cpp')
-rw-r--r-- | lib/Checker/IdempotentOperationChecker.cpp | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/lib/Checker/IdempotentOperationChecker.cpp b/lib/Checker/IdempotentOperationChecker.cpp index 2cfcaa44d4..d8936203ea 100644 --- a/lib/Checker/IdempotentOperationChecker.cpp +++ b/lib/Checker/IdempotentOperationChecker.cpp @@ -74,7 +74,9 @@ class IdempotentOperationChecker void UpdateAssumption(Assumption &A, const Assumption &New); // False positive reduction methods - static bool isParameterSelfAssign(const Expr *LHS, const Expr *RHS); + static bool isUnusedSelfAssign(const Expr *LHS, + const Expr *RHS, + AnalysisContext *AC); static bool isTruncationExtensionAssignment(const Expr *LHS, const Expr *RHS); static bool PathWasCompletelyAnalyzed(const CFG *C, @@ -182,12 +184,19 @@ void IdempotentOperationChecker::PreVisitBinaryOperator( // Fall through intentional case BinaryOperator::Assign: - // x Assign x has a few more false positives we can check for - if (isParameterSelfAssign(RHS, LHS) - || isTruncationExtensionAssignment(RHS, LHS)) { + // x Assign x can be used to silence unused variable warnings intentionally, + // and has a slightly different definition for false positives. + if (isUnusedSelfAssign(RHS, LHS, AC) + || isTruncationExtensionAssignment(RHS, LHS) + || containsNonLocalVarDecl(RHS) + || containsNonLocalVarDecl(LHS)) { A = Impossible; return; } + if (LHSVal != RHSVal) + break; + UpdateAssumption(A, Equal); + return; case BinaryOperator::SubAssign: case BinaryOperator::DivAssign: @@ -397,10 +406,12 @@ inline void IdempotentOperationChecker::UpdateAssumption(Assumption &A, } } -// Check for a statement were a parameter is self assigned (to avoid an unused -// variable warning) -bool IdempotentOperationChecker::isParameterSelfAssign(const Expr *LHS, - const Expr *RHS) { +// Check for a statement where a variable is self assigned to avoid an unused +// variable warning. We still report if the variable is used after the self +// assignment. +bool IdempotentOperationChecker::isUnusedSelfAssign(const Expr *LHS, + const Expr *RHS, + AnalysisContext *AC) { LHS = LHS->IgnoreParenCasts(); RHS = RHS->IgnoreParenCasts(); @@ -408,15 +419,22 @@ bool IdempotentOperationChecker::isParameterSelfAssign(const Expr *LHS, if (!LHS_DR) return false; - const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(LHS_DR->getDecl()); - if (!PD) + const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl()); + if (!VD) return false; const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS); if (!RHS_DR) return false; - return PD == RHS_DR->getDecl(); + if (VD != RHS_DR->getDecl()) + return false; + + // If the var was used outside of a selfassign, then we should still report + if (AC->getPseudoConstantAnalysis()->wasReferenced(VD)) + return false; + + return true; } // Check for self casts truncating/extending a variable |