Author: george.karpenkov Date: Tue Jan 9 17:22:14 2018 New Revision: 322149
URL: http://llvm.org/viewvc/llvm-project?rev=322149&view=rev Log: [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 Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp cfe/trunk/test/Analysis/inlining/false-positive-suppression.c Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=322149&r1=322148&r2=322149&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Tue Jan 9 17:22:14 2018 @@ -839,6 +839,13 @@ const char *SuppressInlineDefensiveCheck 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::Vi 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::Vi 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; } } Modified: cfe/trunk/test/Analysis/inlining/false-positive-suppression.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/false-positive-suppression.c?rev=322149&r1=322148&r2=322149&view=diff ============================================================================== --- cfe/trunk/test/Analysis/inlining/false-positive-suppression.c (original) +++ cfe/trunk/test/Analysis/inlining/false-positive-suppression.c Tue Jan 9 17:22:14 2018 @@ -163,6 +163,7 @@ void testNestedDisjunctiveMacro2(int *p, } + // 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" // -------------------------- _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits