diff options
author | 2020-08-03 14:31:31 +0000 | |
---|---|---|
committer | 2020-08-03 14:31:31 +0000 | |
commit | e5dd70708596ae51455a0ffa086a00c5b29f8583 (patch) | |
tree | 5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.tar.xz wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp')
-rw-r--r-- | gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp new file mode 100644 index 00000000000..85f60231a27 --- /dev/null +++ b/gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp @@ -0,0 +1,132 @@ +//== SimpleConstraintManager.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 file defines SimpleConstraintManager, a class that provides a +// simplified constraint manager interface, compared to ConstraintManager. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" + +namespace clang { + +namespace ento { + +SimpleConstraintManager::~SimpleConstraintManager() {} + +ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State, + DefinedSVal Cond, + bool Assumption) { + // If we have a Loc value, cast it to a bool NonLoc first. + if (Optional<Loc> LV = Cond.getAs<Loc>()) { + SValBuilder &SVB = State->getStateManager().getSValBuilder(); + QualType T; + const MemRegion *MR = LV->getAsRegion(); + if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR)) + T = TR->getLocationType(); + else + T = SVB.getContext().VoidPtrTy; + + Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>(); + } + + return assume(State, Cond.castAs<NonLoc>(), Assumption); +} + +ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State, + NonLoc Cond, bool Assumption) { + State = assumeAux(State, Cond, Assumption); + if (NotifyAssumeClients && SU) + return SU->processAssume(State, Cond, Assumption); + return State; +} + +ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State, + NonLoc Cond, + bool Assumption) { + + // We cannot reason about SymSymExprs, and can only reason about some + // SymIntExprs. + if (!canReasonAbout(Cond)) { + // Just add the constraint to the expression without trying to simplify. + SymbolRef Sym = Cond.getAsSymExpr(); + assert(Sym); + return assumeSymUnsupported(State, Sym, Assumption); + } + + switch (Cond.getSubKind()) { + default: + llvm_unreachable("'Assume' not implemented for this NonLoc"); + + case nonloc::SymbolValKind: { + nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>(); + SymbolRef Sym = SV.getSymbol(); + assert(Sym); + return assumeSym(State, Sym, Assumption); + } + + case nonloc::ConcreteIntKind: { + bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0; + bool isFeasible = b ? Assumption : !Assumption; + return isFeasible ? State : nullptr; + } + + case nonloc::PointerToMemberKind: { + bool IsNull = !Cond.castAs<nonloc::PointerToMember>().isNullMemberPointer(); + bool IsFeasible = IsNull ? Assumption : !Assumption; + return IsFeasible ? State : nullptr; + } + + case nonloc::LocAsIntegerKind: + return assume(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(), + Assumption); + } // end switch +} + +ProgramStateRef SimpleConstraintManager::assumeInclusiveRange( + ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, + const llvm::APSInt &To, bool InRange) { + + assert(From.isUnsigned() == To.isUnsigned() && + From.getBitWidth() == To.getBitWidth() && + "Values should have same types!"); + + if (!canReasonAbout(Value)) { + // Just add the constraint to the expression without trying to simplify. + SymbolRef Sym = Value.getAsSymExpr(); + assert(Sym); + return assumeSymInclusiveRange(State, Sym, From, To, InRange); + } + + switch (Value.getSubKind()) { + default: + llvm_unreachable("'assumeInclusiveRange' is not implemented" + "for this NonLoc"); + + case nonloc::LocAsIntegerKind: + case nonloc::SymbolValKind: { + if (SymbolRef Sym = Value.getAsSymbol()) + return assumeSymInclusiveRange(State, Sym, From, To, InRange); + return State; + } // end switch + + case nonloc::ConcreteIntKind: { + const llvm::APSInt &IntVal = Value.castAs<nonloc::ConcreteInt>().getValue(); + bool IsInRange = IntVal >= From && IntVal <= To; + bool isFeasible = (IsInRange == InRange); + return isFeasible ? State : nullptr; + } + } // end switch +} + +} // end of namespace ento + +} // end of namespace clang |