summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerdim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commit952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
parentea266cad53e3d49771fa38103913d3ec7a166694 (diff)
downloadFreeBSD-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.cpp90
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;
OpenPOWER on IntegriCloud