diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-06-19 23:33:42 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-06-19 23:33:42 +0000 |
commit | 44820630dfa45bc47748a5abda7d4a9cb86da2c1 (patch) | |
tree | 94cc27f4a5871fd5e86e8a8bb45dbdb158b765e5 /clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp | |
parent | 3707b05211f90f2d3b8f31d15b59e8f6c12f3b8b (diff) | |
download | bcm5719-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.cpp | 31 |
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"); |