From 8d0b5771e42ee079be1cb3475a65af2220847a44 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 10 Feb 2018 03:14:22 +0000 Subject: [PATCH] [analyzer] NFC: Assert that our fix for noreturn destructors keeps working. Massive false positives were known to be caused by continuing the analysis after a destructor with a noreturn attribute has been executed in the program but not modeled in the analyzer due to being missing in the CFG. Now that work is being done on enabling the modeling of temporary constructors and destructors in the CFG, we need to make sure that the heuristic that suppresses these false positives keeps working when such modeling is disabled. In particular, different code paths open up when the corresponding constructor is being inlined during analysis. Differential Revision: https://reviews.llvm.org/D42779 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324802 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 6786c89c8f..3135140287 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -356,20 +356,30 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, // paths when no-return temporary destructors are used for assertions. const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext(); if (!ADC->getCFGBuildOptions().AddTemporaryDtors) { - const MemRegion *Target = Call->getCXXThisVal().getAsRegion(); - if (Target && isa(Target) && - Call->getDecl()->getParent()->isAnyDestructorNoReturn()) { + const MemRegion *Target = Call->getCXXThisVal().getAsRegion(); + if (Target && isa(Target) && + Call->getDecl()->getParent()->isAnyDestructorNoReturn()) { + + // If we've inlined the constructor, then DstEvaluated would be empty. + // In this case we still want a sink, which could be implemented + // in processCallExit. But we don't have that implemented at the moment, + // so if you hit this assertion, see if you can avoid inlining + // the respective constructor when analyzer-config cfg-temporary-dtors + // is set to false. + // Otherwise there's nothing wrong with inlining such constructor. + assert(!DstEvaluated.empty() && + "We should not have inlined this constructor!"); for (ExplodedNode *N : DstEvaluated) { Bldr.generateSink(CE, N, N->getState()); } - // There is no need to run the PostCall and PostStmtchecker + // There is no need to run the PostCall and PostStmt checker // callbacks because we just generated sinks on all nodes in th // frontier. return; } - } + } ExplodedNodeSet DstPostCall; getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, -- 2.40.0