defaultEvalCall(Bldr, *I, *Call);
}
+ // If the CFG was contructed without elements for temporary destructors
+ // and the just-called constructor created a temporary object then
+ // stop exploration if the temporary object has a noreturn constructor.
+ // This can lose coverage because the destructor, if it were present
+ // in the CFG, would be called at the end of the full expression or
+ // later (for life-time extended temporaries) -- but avoids infeasible
+ // 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<CXXTempObjectRegion>(Target) &&
+ Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+ for (ExplodedNode *N : DstEvaluated) {
+ Bldr.generateSink(CE, N, N->getState());
+ }
+
+ // There is no need to run the PostCall and PostStmtchecker
+ // callbacks because we just generated sinks on all nodes in th
+ // frontier.
+ return;
+ }
+ }
+
ExplodedNodeSet DstPostCall;
getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
*Call, *this);
value ? DefaultParam(42) : DefaultParam(42);
}
}
+#else // !TEMPORARY_DTORS
+
+// Test for fallback logic that conservatively stops exploration after
+// executing a temporary constructor for a class with a no-return destructor
+// when temporary destructors are not enabled in the CFG.
+
+ struct CtorWithNoReturnDtor {
+ CtorWithNoReturnDtor() = default;
+
+ ~CtorWithNoReturnDtor() __attribute__((noreturn));
+ };
+
+ void testDefaultContructorWithNoReturnDtor() {
+ CtorWithNoReturnDtor();
+ clang_analyzer_warnIfReached(); // no-warning
+ }
+
+ void testLifeExtensionWithNoReturnDtor() {
+ const CtorWithNoReturnDtor &c = CtorWithNoReturnDtor();
+
+ // This represents an (expected) loss of coverage, since the destructor
+ // of the lifetime-exended temporary is executed at at the end of
+ // scope.
+ clang_analyzer_warnIfReached(); // no-warning
+ }
+
#endif // TEMPORARY_DTORS
}