зеркало из https://github.com/microsoft/clang-1.git
[analyzer] Allow suppressing diagnostics reported within the 'std' namespace
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
This commit is contained in:
Родитель
f12a25b55b
Коммит
a12643622a
|
@ -217,6 +217,9 @@ private:
|
|||
/// \sa shouldSuppressInlinedDefensiveChecks
|
||||
Optional<bool> SuppressInlinedDefensiveChecks;
|
||||
|
||||
/// \sa shouldSuppressFromCXXStandardLibrary
|
||||
Optional<bool> SuppressFromCXXStandardLibrary;
|
||||
|
||||
/// \sa getGraphTrimInterval
|
||||
Optional<unsigned> GraphTrimInterval;
|
||||
|
||||
|
@ -306,6 +309,13 @@ public:
|
|||
/// 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.
|
||||
///
|
||||
|
|
|
@ -158,6 +158,12 @@ bool AnalyzerOptions::shouldSuppressInlinedDefensiveChecks() {
|
|||
/* 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);
|
||||
|
|
|
@ -1421,28 +1421,53 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
|
|||
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;
|
||||
|
|
|
@ -73,6 +73,13 @@ namespace std {
|
|||
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();
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// 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.
|
Загрузка…
Ссылка в новой задаче