summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-06-19 23:33:42 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-06-19 23:33:42 +0000
commit44820630dfa45bc47748a5abda7d4a9cb86da2c1 (patch)
tree94cc27f4a5871fd5e86e8a8bb45dbdb158b765e5 /clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
parent3707b05211f90f2d3b8f31d15b59e8f6c12f3b8b (diff)
downloadbcm5719-llvm-44820630dfa45bc47748a5abda7d4a9cb86da2c1.tar.gz
bcm5719-llvm-44820630dfa45bc47748a5abda7d4a9cb86da2c1.zip
[analyzer] NFC: Change evalCall() to provide a CallEvent.
This changes the checker callback signature to use the modern, easy to use interface. Additionally, this unblocks future work on allowing checkers to implement evalCall() for calls that don't correspond to any call-expression or require additional information that's only available as part of the CallEvent, such as C++ constructors and destructors. Differential Revision: https://reviews.llvm.org/D62440 llvm-svn: 363893
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp31
1 files changed, 18 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 8544f98b948..10594e331cb 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -14,6 +14,7 @@
#include "clang/Basic/Builtins.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
using namespace clang;
@@ -23,30 +24,32 @@ namespace {
class BuiltinFunctionChecker : public Checker<eval::Call> {
public:
- bool evalCall(const CallExpr *CE, CheckerContext &C) const;
+ bool evalCall(const CallEvent &Call, CheckerContext &C) const;
};
}
-bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
+bool BuiltinFunctionChecker::evalCall(const CallEvent &Call,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
- const FunctionDecl *FD = C.getCalleeDecl(CE);
- const LocationContext *LCtx = C.getLocationContext();
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
if (!FD)
return false;
+ const LocationContext *LCtx = C.getLocationContext();
+ const Expr *CE = Call.getOriginExpr();
+
switch (FD->getBuiltinID()) {
default:
return false;
case Builtin::BI__builtin_assume: {
- assert (CE->arg_begin() != CE->arg_end());
- SVal ArgSVal = C.getSVal(CE->getArg(0));
- if (ArgSVal.isUndef())
+ assert (Call.getNumArgs() > 0);
+ SVal Arg = Call.getArgSVal(0);
+ if (Arg.isUndef())
return true; // Return true to model purity.
- state = state->assume(ArgSVal.castAs<DefinedOrUnknownSVal>(), true);
+ state = state->assume(Arg.castAs<DefinedOrUnknownSVal>(), true);
// FIXME: do we want to warn here? Not right now. The most reports might
// come from infeasible paths, thus being false positives.
if (!state) {
@@ -66,9 +69,9 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
// __builtin_assume_aligned, just return the value of the subexpression.
// __builtin_addressof is going from a reference to a pointer, but those
// are represented the same way in the analyzer.
- assert (CE->arg_begin() != CE->arg_end());
- SVal X = C.getSVal(*(CE->arg_begin()));
- C.addTransition(state->BindExpr(CE, LCtx, X));
+ assert (Call.getNumArgs() > 0);
+ SVal Arg = Call.getArgSVal(0);
+ C.addTransition(state->BindExpr(CE, LCtx, Arg));
return true;
}
@@ -82,12 +85,14 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
// Set the extent of the region in bytes. This enables us to use the
// SVal of the argument directly. If we save the extent in bits, we
// cannot represent values like symbol*8.
- auto Size = C.getSVal(*(CE->arg_begin())).castAs<DefinedOrUnknownSVal>();
+ auto Size = Call.getArgSVal(0);
+ if (Size.isUndef())
+ return true; // Return true to model purity.
SValBuilder& svalBuilder = C.getSValBuilder();
DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
DefinedOrUnknownSVal extentMatchesSizeArg =
- svalBuilder.evalEQ(state, Extent, Size);
+ svalBuilder.evalEQ(state, Extent, Size.castAs<DefinedOrUnknownSVal>());
state = state->assume(extentMatchesSizeArg, true);
assert(state && "The region should not have any previous constraints");
OpenPOWER on IntegriCloud