diff options
author | dim <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 |
commit | 952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch) | |
tree | df8df0b0067b381eab470a3b8f28d14a552a6340 /lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | |
parent | ea266cad53e3d49771fa38103913d3ec7a166694 (diff) | |
download | FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.zip FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.tar.gz |
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841
Diffstat (limited to 'lib/StaticAnalyzer/Core/BugReporterVisitors.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index e078745..e1a92b3 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -532,7 +532,8 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, // If we have an expression that provided the value, try to track where it // came from. if (InitE) { - if (V.isUndef() || V.getAs<loc::ConcreteInt>()) { + if (V.isUndef() || + V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) { if (!IsParam) InitE = InitE->IgnoreParenCasts(); bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam, @@ -697,10 +698,13 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, if (P.getAs<CallEnter>() && InitE) L = PathDiagnosticLocation(InitE, BRC.getSourceManager(), P.getLocationContext()); - else + + if (!L.isValid() || !L.asLocation().isValid()) L = PathDiagnosticLocation::create(P, BRC.getSourceManager()); - if (!L.isValid()) + + if (!L.isValid() || !L.asLocation().isValid()) return NULL; + return new PathDiagnosticEventPiece(L, os.str()); } @@ -993,12 +997,15 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, BugReporterVisitor *ConstraintTracker = new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false); report.addVisitor(ConstraintTracker); + } - // Add visitor, which will suppress inline defensive checks. - if (LVState->isNull(V).isConstrainedTrue() && - EnableNullFPSuppression) { + // Add visitor, which will suppress inline defensive checks. + if (Optional<DefinedSVal> DV = V.getAs<DefinedSVal>()) { + if (!DV->isZeroConstant() && + LVState->isNull(*DV).isConstrainedTrue() && + EnableNullFPSuppression) { BugReporterVisitor *IDCSuppressor = - new SuppressInlineDefensiveChecksVisitor(V.castAs<DefinedSVal>(), + new SuppressInlineDefensiveChecksVisitor(*DV, LVNode); report.addVisitor(IDCSuppressor); } @@ -1350,7 +1357,8 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, // For non-assignment operations, we require that we can understand // both the LHS and RHS. - if (LhsString.empty() || RhsString.empty()) + if (LhsString.empty() || RhsString.empty() || + !BinaryOperator::isComparisonOp(Op)) return 0; // Should we invert the strings if the LHS is not a variable name? @@ -1462,9 +1470,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, SmallString<256> Buf; llvm::raw_svector_ostream Out(Buf); - Out << "Assuming '"; - VD->getDeclName().printName(Out); - Out << "' is "; + Out << "Assuming '" << VD->getDeclName() << "' is "; QualType VDTy = VD->getType(); @@ -1516,18 +1522,59 @@ LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC, BugReport &BR) { // Here we suppress false positives coming from system headers. This list is // based on known issues. - - // Skip reports within the 'std' namespace. Although these can sometimes be - // the user's fault, we currently don't report them very well, and - // Note that this will not help for any other data structure libraries, like - // TR1, Boost, or llvm/ADT. ExprEngine &Eng = BRC.getBugReporter().getEngine(); AnalyzerOptions &Options = Eng.getAnalysisManager().options; - if (Options.shouldSuppressFromCXXStandardLibrary()) { - const LocationContext *LCtx = N->getLocationContext(); - if (isInStdNamespace(LCtx->getDecl())) { + const Decl *D = N->getLocationContext()->getDecl(); + + if (isInStdNamespace(D)) { + // Skip reports within the 'std' namespace. Although these can sometimes be + // the user's fault, we currently don't report them very well, and + // Note that this will not help for any other data structure libraries, like + // TR1, Boost, or llvm/ADT. + if (Options.shouldSuppressFromCXXStandardLibrary()) { BR.markInvalid(getTag(), 0); return 0; + + } else { + // If the the complete 'std' suppression is not enabled, suppress reports + // from the 'std' namespace that are known to produce false positives. + + // The analyzer issues a false use-after-free when std::list::pop_front + // or std::list::pop_back are called multiple times because we cannot + // reason about the internal invariants of the datastructure. + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { + const CXXRecordDecl *CD = MD->getParent(); + if (CD->getName() == "list") { + BR.markInvalid(getTag(), 0); + return 0; + } + } + + // The analyzer issues a false positive on + // std::basic_string<uint8_t> v; v.push_back(1); + // and + // std::u16string s; s += u'a'; + // because we cannot reason about the internal invariants of the + // datastructure. + const LocationContext *LCtx = N->getLocationContext(); + do { + const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl()); + if (!MD) + break; + + const CXXRecordDecl *CD = MD->getParent(); + if (CD->getName() == "basic_string") { + BR.markInvalid(getTag(), 0); + return 0; + } else if (CD->getName().find("allocator") == StringRef::npos) { + // Only keep searching if the current method is in a class with the + // word "allocator" in its name, e.g. std::allocator or + // allocator_traits. + break; + } + + LCtx = LCtx->getParent(); + } while (LCtx); } } @@ -1536,12 +1583,11 @@ LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC, SourceManager &SM = BRC.getSourceManager(); FullSourceLoc Loc = BR.getLocation(SM).asLocation(); while (Loc.isMacroID()) { - if (SM.isInSystemMacro(Loc) && - (SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) { + Loc = Loc.getSpellingLoc(); + if (SM.getFilename(Loc).endswith("sys/queue.h")) { BR.markInvalid(getTag(), 0); return 0; } - Loc = Loc.getSpellingLoc(); } return 0; |