Skip to content

Commit

Permalink
[analyzer] suppress nullability inference from a macro when result is…
Browse files Browse the repository at this point in the history
… used in another macro

The current code used to not suppress the report, if the dereference was
performed in a macro, assuming it is that same macro.
However, the assumption might not be correct, and XNU has quite a bit of
code where dereference is actually performed in a different macro.

As the code uses macro name and not a unique identifier it might be fragile,
but in a worst-case scenario we would simply emit an extra diagnostic.

rdar://36160245

Differential Revision: https://reviews.llvm.org/D41749

llvm-svn: 322149
  • Loading branch information
George Karpenkov committed Jan 10, 2018
1 parent 5fa274b commit 77dfbf2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
18 changes: 14 additions & 4 deletions clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
Expand Up @@ -839,6 +839,13 @@ const char *SuppressInlineDefensiveChecksVisitor::getTag() {
return "IDCVisitor";
}

/// \return name of the macro inside the location \p Loc.
static StringRef getMacroName(SourceLocation Loc,
BugReporterContext &BRC) {
return Lexer::getImmediateMacroName(
Loc, BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
}

std::shared_ptr<PathDiagnosticPiece>
SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
const ExplodedNode *Pred,
Expand Down Expand Up @@ -878,9 +885,6 @@ SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
if (!BugPoint)
return nullptr;

SourceLocation BugLoc = BugPoint->getStmt()->getLocStart();
if (BugLoc.isMacroID())
return nullptr;

ProgramPoint CurPoint = Succ->getLocation();
const Stmt *CurTerminatorStmt = nullptr;
Expand All @@ -907,7 +911,13 @@ SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
SrcMgr::SLocEntry SE = SMgr.getSLocEntry(TLInfo.first);
const SrcMgr::ExpansionInfo &EInfo = SE.getExpansion();
if (EInfo.isFunctionMacroExpansion()) {
BR.markInvalid("Suppress Macro IDC", CurLC);
SourceLocation BugLoc = BugPoint->getStmt()->getLocStart();

// Suppress reports unless we are in that same macro.
if (!BugLoc.isMacroID() ||
getMacroName(BugLoc, BRC) != getMacroName(TerminatorLoc, BRC)) {
BR.markInvalid("Suppress Macro IDC", CurLC);
}
return nullptr;
}
}
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Analysis/inlining/false-positive-suppression.c
Expand Up @@ -163,6 +163,7 @@ void testNestedDisjunctiveMacro2(int *p, int *q) {
}



// Here the check is entirely in non-macro code even though the code itself
// is a macro argument.
#define MACRO_DO_IT(a) (a)
Expand All @@ -171,6 +172,15 @@ void testErrorInArgument(int *p) {
(void)i;
}

// No warning should be emitted if dereference is performed from a different
// macro.
#define MACRO_CHECK(a) if (a) {}
#define MACRO_DEREF(a) (*a)
int testDifferentMacro(int *p) {
MACRO_CHECK(p);
return MACRO_DEREF(p); // no-warning
}

// --------------------------
// "Suppression suppression"
// --------------------------
Expand Down

0 comments on commit 77dfbf2

Please sign in to comment.