summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
commite5dd70708596ae51455a0ffa086a00c5b29f8583 (patch)
tree5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-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.cpp132
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