This is controlled by the 'suppress-c++-stdlib' analyzer-config flag.
It is currently off by default.
This is more suppression than we'd like to do, since obviously there can
be user-caused issues within 'std', but it gives us the option to wield
a large hammer to suppress false positives the user likely can't work
around.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178513
91177308-0d34-0410-b5e6-
96231b3b80d8
/// \sa shouldSuppressInlinedDefensiveChecks
Optional<bool> SuppressInlinedDefensiveChecks;
+ /// \sa shouldSuppressFromCXXStandardLibrary
+ Optional<bool> SuppressFromCXXStandardLibrary;
+
/// \sa getGraphTrimInterval
Optional<unsigned> GraphTrimInterval;
/// option, which accepts the values "true" and "false".
bool shouldSuppressInlinedDefensiveChecks();
+ /// Returns whether or not diagnostics reported within the C++ standard
+ /// library should be suppressed.
+ ///
+ /// This is controlled by the 'suppress-c++-stdlib' config option,
+ /// which accepts the values "true" and "false".
+ bool shouldSuppressFromCXXStandardLibrary();
+
/// Returns whether irrelevant parts of a bug report path should be pruned
/// out of the final output.
///
/* Default = */ true);
}
+bool AnalyzerOptions::shouldSuppressFromCXXStandardLibrary() {
+ return getBooleanOption(SuppressFromCXXStandardLibrary,
+ "suppress-c++-stdlib",
+ /* Default = */ false);
+}
+
int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
SmallString<10> StrBuf;
llvm::raw_svector_ostream OS(StrBuf);
return event;
}
+
+// FIXME: Copied from ExprEngineCallAndReturn.cpp.
+static bool isInStdNamespace(const Decl *D) {
+ const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
+ const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
+ if (!ND)
+ return false;
+
+ while (const NamespaceDecl *Parent = dyn_cast<NamespaceDecl>(ND->getParent()))
+ ND = Parent;
+
+ return ND->getName() == "std";
+}
+
+
PathDiagnosticPiece *
LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
BugReport &BR) {
- const Stmt *S = BR.getStmt();
- if (!S)
- return 0;
-
- // Here we suppress false positives coming from system macros. This list is
+ // 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())) {
+ BR.markInvalid(getTag(), 0);
+ return 0;
+ }
+ }
+
// Skip reports within the sys/queue.h macros as we do not have the ability to
// reason about data structure shapes.
SourceManager &SM = BRC.getSourceManager();
- SourceLocation Loc = S->getLocStart();
+ FullSourceLoc Loc = BR.getLocation(SM).asLocation();
while (Loc.isMacroID()) {
if (SM.isInSystemMacro(Loc) &&
(SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) {
BR.markInvalid(getTag(), 0);
return 0;
}
- Loc = SM.getSpellingLoc(Loc);
+ Loc = Loc.getSpellingLoc();
}
return 0;
struct nothrow_t {};
extern const nothrow_t nothrow;
+
+ template<class InputIter, class OutputIter>
+ OutputIter copy(InputIter II, InputIter IE, OutputIter OI) {
+ while (II != IE)
+ *OI++ = *II++;
+ return OI;
+ }
}
void* operator new(std::size_t, const std::nothrow_t&) throw();
--- /dev/null
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s
+
+#ifdef SUPPRESSED
+// expected-no-diagnostics
+#endif
+
+#include "../Inputs/system-header-simulator-cxx.h"
+
+void clang_analyzer_eval(bool);
+
+void testCopyNull(int *I, int *E) {
+ std::copy(I, E, (int *)0);
+#ifndef SUPPRESSED
+ // This line number comes from system-header-simulator-cxx.h.
+ // expected-warning@65 {{Dereference of null pointer}}
+#endif
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// PR15613: expected-* can't refer to diagnostics in other source files.
+// The current implementation only matches line numbers, but has an upper limit
+// of the number of lines in the main source file.