summaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index dee34e3e9d6a..75d7e265af0f 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -909,7 +909,14 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
ExplodedNodeSet DstPostCall;
StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
for (ExplodedNode *I : DstPreCall) {
- // FIXME: Provide evalCall for checkers?
+ // Operator new calls (CXXNewExpr) are intentionally not eval-called,
+ // because it does not make sense to eval-call user-provided functions.
+ // 1) If the new operator can be inlined, then don't prevent it from
+ // inlining by having an eval-call of that operator.
+ // 2) If it can't be inlined, then the default conservative modeling
+ // is what we want anyway.
+ // So the best is to not allow eval-calling CXXNewExprs from checkers.
+ // Checkers can provide their pre/post-call callbacks if needed.
defaultEvalCall(CallBldr, I, *Call);
}
// If the call is inlined, DstPostCall will be empty and we bail out now.
@@ -1110,6 +1117,10 @@ void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
for (ExplodedNode *I : DstPreCall) {
+ // Intentionally either inline or conservative eval-call the operator
+ // delete, but avoid triggering an eval-call event for checkers.
+ // As detailed at handling CXXNewExprs, in short, because it does not
+ // really make sense to eval-call user-provided functions.
defaultEvalCall(Bldr, I, *Call);
}
} else {