Path: blob/main/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/AssumeModeling.cpp
213799 views
//=== AssumeModeling.cpp --------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This checker evaluates the builting assume functions.9// This checker also sinks execution paths leaving [[assume]] attributes with10// false assumptions.11//12//===----------------------------------------------------------------------===//1314#include "clang/AST/AttrIterator.h"15#include "clang/Basic/Builtins.h"16#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"17#include "clang/StaticAnalyzer/Core/Checker.h"18#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"19#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"20#include "llvm/ADT/STLExtras.h"2122using namespace clang;23using namespace ento;2425namespace {26class AssumeModelingChecker27: public Checker<eval::Call, check::PostStmt<AttributedStmt>> {28public:29void checkPostStmt(const AttributedStmt *A, CheckerContext &C) const;30bool evalCall(const CallEvent &Call, CheckerContext &C) const;31};32} // namespace3334void AssumeModelingChecker::checkPostStmt(const AttributedStmt *A,35CheckerContext &C) const {36if (!hasSpecificAttr<CXXAssumeAttr>(A->getAttrs()))37return;3839for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {40SVal AssumptionVal = C.getSVal(Attr->getAssumption());4142// The assumption is not evaluated at all if it had sideffects; skip them.43if (AssumptionVal.isUnknown())44continue;4546const auto *Assumption = AssumptionVal.getAsInteger();47if (Assumption && Assumption->isZero()) {48C.addSink();49}50}51}5253bool AssumeModelingChecker::evalCall(const CallEvent &Call,54CheckerContext &C) const {55ProgramStateRef State = C.getState();56const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());57if (!FD)58return false;5960if (!llvm::is_contained({Builtin::BI__builtin_assume, Builtin::BI__assume},61FD->getBuiltinID())) {62return false;63}6465assert(Call.getNumArgs() > 0);66SVal Arg = Call.getArgSVal(0);67if (Arg.isUndef())68return true; // Return true to model purity.6970State = State->assume(Arg.castAs<DefinedOrUnknownSVal>(), true);71if (!State) {72C.addSink();73return true;74}7576C.addTransition(State);77return true;78}7980void ento::registerAssumeModeling(CheckerManager &Mgr) {81Mgr.registerChecker<AssumeModelingChecker>();82}8384bool ento::shouldRegisterAssumeModeling(const CheckerManager &) { return true; }858687