aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp9
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp13
5 files changed, 28 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
index e64153d..309e3d2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -129,7 +129,8 @@ public:
llvm::errs() << " {argno: " << Call.getNumArgs() << '}';
llvm::errs() << " [" << Call.getKindAsString() << ']';
llvm::errs() << '\n';
- return true;
+ // We can't return `true` from this callback without binding the return
+ // value. Let's just fallthrough here and return `false`.
}
return false;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 36f316d..0ae784c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -672,6 +672,10 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
ProgramStateRef stateTrue, stateFalse;
+ if (!First.Expression->getType()->isAnyPointerType() ||
+ !Second.Expression->getType()->isAnyPointerType())
+ return state;
+
// Assume different address spaces cannot overlap.
if (First.Expression->getType()->getPointeeType().getAddressSpace() !=
Second.Expression->getType()->getPointeeType().getAddressSpace())
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 392c7ee..c716235 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -262,6 +262,15 @@ public:
/// state. This callback allows a checker to provide domain specific knowledge
/// about the particular functions it knows about.
///
+ /// Note that to evaluate a call, the handler MUST bind the return value if
+ /// its a non-void function. Invalidate the arguments if necessary.
+ ///
+ /// Note that in general, user-provided functions should not be eval-called
+ /// because the checker can't predict the exact semantics/contract of the
+ /// callee, and by having the eval::Call callback, we also prevent it from
+ /// getting inlined, potentially regressing analysis quality.
+ /// Consider using check::PreCall or check::PostCall to allow inlining.
+ ///
/// \returns true if the call has been successfully evaluated
/// and false otherwise. Note, that only one checker can evaluate a call. If
/// more than one checker claims that they can evaluate the same call the
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 785cdfa..4e472b7 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1814,6 +1814,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::OMPStripeDirectiveClass:
case Stmt::OMPTileDirectiveClass:
case Stmt::OMPInterchangeDirectiveClass:
+ case Stmt::OMPFuseDirectiveClass:
case Stmt::OMPInteropDirectiveClass:
case Stmt::OMPDispatchDirectiveClass:
case Stmt::OMPMaskedDirectiveClass:
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index dee34e3..75d7e26 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 {