diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp | 139 |
1 files changed, 0 insertions, 139 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp deleted file mode 100644 index 10594e331cbe..000000000000 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ /dev/null @@ -1,139 +0,0 @@ -//=== BuiltinFunctionChecker.cpp --------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This checker evaluates clang builtin functions. -// -//===----------------------------------------------------------------------===// - -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#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; -using namespace ento; - -namespace { - -class BuiltinFunctionChecker : public Checker<eval::Call> { -public: - bool evalCall(const CallEvent &Call, CheckerContext &C) const; -}; - -} - -bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, - CheckerContext &C) const { - ProgramStateRef state = C.getState(); - 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 (Call.getNumArgs() > 0); - SVal Arg = Call.getArgSVal(0); - if (Arg.isUndef()) - return true; // Return true to model purity. - - 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) { - C.generateSink(C.getState(), C.getPredecessor()); - return true; - } - - C.addTransition(state); - return true; - } - - case Builtin::BI__builtin_unpredictable: - case Builtin::BI__builtin_expect: - case Builtin::BI__builtin_assume_aligned: - case Builtin::BI__builtin_addressof: { - // For __builtin_unpredictable, __builtin_expect, and - // __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 (Call.getNumArgs() > 0); - SVal Arg = Call.getArgSVal(0); - C.addTransition(state->BindExpr(CE, LCtx, Arg)); - return true; - } - - case Builtin::BI__builtin_alloca_with_align: - case Builtin::BI__builtin_alloca: { - // FIXME: Refactor into StoreManager itself? - MemRegionManager& RM = C.getStoreManager().getRegionManager(); - const AllocaRegion* R = - RM.getAllocaRegion(CE, C.blockCount(), C.getLocationContext()); - - // 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 = 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.castAs<DefinedOrUnknownSVal>()); - state = state->assume(extentMatchesSizeArg, true); - assert(state && "The region should not have any previous constraints"); - - C.addTransition(state->BindExpr(CE, LCtx, loc::MemRegionVal(R))); - return true; - } - - case Builtin::BI__builtin_dynamic_object_size: - case Builtin::BI__builtin_object_size: - case Builtin::BI__builtin_constant_p: { - // This must be resolvable at compile time, so we defer to the constant - // evaluator for a value. - SValBuilder &SVB = C.getSValBuilder(); - SVal V = UnknownVal(); - Expr::EvalResult EVResult; - if (CE->EvaluateAsInt(EVResult, C.getASTContext(), Expr::SE_NoSideEffects)) { - // Make sure the result has the correct type. - llvm::APSInt Result = EVResult.Val.getInt(); - BasicValueFactory &BVF = SVB.getBasicValueFactory(); - BVF.getAPSIntType(CE->getType()).apply(Result); - V = SVB.makeIntVal(Result); - } - - if (FD->getBuiltinID() == Builtin::BI__builtin_constant_p) { - // If we didn't manage to figure out if the value is constant or not, - // it is safe to assume that it's not constant and unsafe to assume - // that it's constant. - if (V.isUnknown()) - V = SVB.makeIntVal(0, CE->getType()); - } - - C.addTransition(state->BindExpr(CE, LCtx, V)); - return true; - } - } -} - -void ento::registerBuiltinFunctionChecker(CheckerManager &mgr) { - mgr.registerChecker<BuiltinFunctionChecker>(); -} - -bool ento::shouldRegisterBuiltinFunctionChecker(const LangOptions &LO) { - return true; -} |
