summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
authorDevin Coughlin <dcoughlin@apple.com>2016-07-21 23:42:31 +0000
committerDevin Coughlin <dcoughlin@apple.com>2016-07-21 23:42:31 +0000
commitf57f90dfd1c328fc8bb9d9009be0b7690a7bd761 (patch)
tree5a1492613ac13a456f4b016e80e4c623c9bd957f /clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
parentc107a4875e40d0aceb6f542803fc71e0cfe86e46 (diff)
downloadbcm5719-llvm-f57f90dfd1c328fc8bb9d9009be0b7690a7bd761.tar.gz
bcm5719-llvm-f57f90dfd1c328fc8bb9d9009be0b7690a7bd761.zip
[analyzer] Add checker modeling potential C++ self-assignment
This checker checks copy and move assignment operators whether they are protected against self-assignment. Since C++ core guidelines discourages explicit checking for `&rhs==this` in general we take a different approach: in top-frame analysis we branch the exploded graph for two cases, where &rhs==this and &rhs!=this and let existing checkers (e.g. unix.Malloc) do the rest of the work. It is important that we check all copy and move assignment operator in top frame even if we checked them already since self-assignments may happen undetected even in the same translation unit (e.g. using random indices for an array what may or may not be the same). This reapplies r275820 after fixing a string-lifetime issue discovered by the bots. A patch by Ádám Balogh! Differential Revision: https://reviews.llvm.org/D19311 llvm-svn: 276365
Diffstat (limited to 'clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 3d51062da35..3020ab54d0b 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -426,6 +426,13 @@ static bool shouldSkipFunction(const Decl *D,
// Count naming convention errors more aggressively.
if (isa<ObjCMethodDecl>(D))
return false;
+ // We also want to reanalyze all C++ copy and move assignment operators to
+ // separately check the two cases where 'this' aliases with the parameter and
+ // where it may not. (cplusplus.SelfAssignmentChecker)
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())
+ return false;
+ }
// Otherwise, if we visited the function before, do not reanalyze it.
return Visited.count(D);
@@ -437,9 +444,7 @@ AnalysisConsumer::getInliningModeForFunction(const Decl *D,
// We want to reanalyze all ObjC methods as top level to report Retain
// Count naming convention errors more aggressively. But we should tune down
// inlining when reanalyzing an already inlined function.
- if (Visited.count(D)) {
- assert(isa<ObjCMethodDecl>(D) &&
- "We are only reanalyzing ObjCMethods.");
+ if (Visited.count(D) && isa<ObjCMethodDecl>(D)) {
const ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(D);
if (ObjCM->getMethodFamily() != OMF_init)
return ExprEngine::Inline_Minimal;
OpenPOWER on IntegriCloud