[analyzer] suppress nullability inference from a macro when result is 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
This commit is contained in:
George Karpenkov 2018-01-10 01:22:14 +00:00
parent 5fa274bea4
commit 77dfbf21d1
2 changed files with 24 additions and 4 deletions

View File

@ -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,
@ -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;
@ -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;
}
}

View File

@ -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)
@ -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"
// --------------------------