clang  16.0.0git
SimpleConstraintManager.cpp
Go to the documentation of this file.
1 //== SimpleConstraintManager.cpp --------------------------------*- C++ -*--==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines SimpleConstraintManager, a class that provides a
10 // simplified constraint manager interface, compared to ConstraintManager.
11 //
12 //===----------------------------------------------------------------------===//
13 
18 
19 namespace clang {
20 
21 namespace ento {
22 
24 
26  DefinedSVal Cond,
27  bool Assumption) {
28  // If we have a Loc value, cast it to a bool NonLoc first.
29  if (Optional<Loc> LV = Cond.getAs<Loc>()) {
30  SValBuilder &SVB = State->getStateManager().getSValBuilder();
31  QualType T;
32  const MemRegion *MR = LV->getAsRegion();
33  if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))
34  T = TR->getLocationType();
35  else
36  T = SVB.getContext().VoidPtrTy;
37 
38  Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();
39  }
40 
41  return assume(State, Cond.castAs<NonLoc>(), Assumption);
42 }
43 
44 ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
45  NonLoc Cond, bool Assumption) {
46  State = assumeAux(State, Cond, Assumption);
47  if (EE)
48  return EE->processAssume(State, Cond, Assumption);
49  return State;
50 }
51 
52 ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,
53  NonLoc Cond,
54  bool Assumption) {
55 
56  // We cannot reason about SymSymExprs, and can only reason about some
57  // SymIntExprs.
58  if (!canReasonAbout(Cond)) {
59  // Just add the constraint to the expression without trying to simplify.
60  SymbolRef Sym = Cond.getAsSymbol();
61  assert(Sym);
62  return assumeSymUnsupported(State, Sym, Assumption);
63  }
64 
65  switch (Cond.getSubKind()) {
66  default:
67  llvm_unreachable("'Assume' not implemented for this NonLoc");
68 
69  case nonloc::SymbolValKind: {
70  nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
71  SymbolRef Sym = SV.getSymbol();
72  assert(Sym);
73  return assumeSym(State, Sym, Assumption);
74  }
75 
76  case nonloc::ConcreteIntKind: {
77  bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
78  bool isFeasible = b ? Assumption : !Assumption;
79  return isFeasible ? State : nullptr;
80  }
81 
82  case nonloc::PointerToMemberKind: {
83  bool IsNull = !Cond.castAs<nonloc::PointerToMember>().isNullMemberPointer();
84  bool IsFeasible = IsNull ? Assumption : !Assumption;
85  return IsFeasible ? State : nullptr;
86  }
87 
88  case nonloc::LocAsIntegerKind:
89  return assumeInternal(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
90  Assumption);
91  } // end switch
92 }
93 
96  const llvm::APSInt &To, bool InRange) {
97 
98  assert(From.isUnsigned() == To.isUnsigned() &&
99  From.getBitWidth() == To.getBitWidth() &&
100  "Values should have same types!");
101 
102  if (!canReasonAbout(Value)) {
103  // Just add the constraint to the expression without trying to simplify.
104  SymbolRef Sym = Value.getAsSymbol();
105  assert(Sym);
106  return assumeSymInclusiveRange(State, Sym, From, To, InRange);
107  }
108 
109  switch (Value.getSubKind()) {
110  default:
111  llvm_unreachable("'assumeInclusiveRange' is not implemented"
112  "for this NonLoc");
113 
114  case nonloc::LocAsIntegerKind:
115  case nonloc::SymbolValKind: {
116  if (SymbolRef Sym = Value.getAsSymbol())
117  return assumeSymInclusiveRange(State, Sym, From, To, InRange);
118  return State;
119  } // end switch
120 
121  case nonloc::ConcreteIntKind: {
122  const llvm::APSInt &IntVal = Value.castAs<nonloc::ConcreteInt>().getValue();
123  bool IsInRange = IntVal >= From && IntVal <= To;
124  bool isFeasible = (IsInRange == InRange);
125  return isFeasible ? State : nullptr;
126  }
127  } // end switch
128 }
129 
130 } // end of namespace ento
131 
132 } // end of namespace clang
clang::ento::SimpleConstraintManager::assumeInclusiveRangeInternal
ProgramStateRef assumeInclusiveRangeInternal(ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange) override
Definition: SimpleConstraintManager.cpp:94
clang::ento::ConstraintManager::canReasonAbout
virtual bool canReasonAbout(SVal X) const =0
canReasonAbout - Not all ConstraintManagers can accurately reason about all SVal values.
clang::ento::SVal::castAs
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:100
clang::ento::NonLoc
Definition: SVals.h:266
clang::ento::SimpleConstraintManager::assumeSymUnsupported
virtual ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym, bool Assumption)=0
Given a symbolic expression that cannot be reasoned about, assume that it is zero/nonzero and add it ...
clang::ento::ProgramStateRef
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Definition: ProgramState_Fwd.h:37
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::ento::SymbolRef
const SymExpr * SymbolRef
Definition: SymExpr.h:111
llvm::Optional
Definition: LLVM.h:40
clang::ento::nonloc::ConcreteInt
Value representing integer constant.
Definition: SVals.h:330
b
__device__ __2f16 b
Definition: __clang_hip_libdevice_declares.h:319
clang::ento::SVal::getAs
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type.
Definition: SVals.h:104
getValue
static SVal getValue(SVal val, SValBuilder &svalBuilder)
Definition: ArrayBoundCheckerV2.cpp:276
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:95
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::ento::DefinedSVal
Definition: SVals.h:243
clang::ento::SValBuilder::getContext
ASTContext & getContext()
Definition: SValBuilder.h:136
clang::ento::SymExpr
Symbolic value.
Definition: SymExpr.h:29
clang::prec::PointerToMember
@ PointerToMember
Definition: OperatorPrecedence.h:42
SimpleConstraintManager.h
clang::ento::Loc
Definition: SVals.h:282
clang::interp::InRange
bool InRange(InterpState &S, CodePtr OpPC)
Definition: Interp.h:531
clang::ento::SimpleConstraintManager::~SimpleConstraintManager
~SimpleConstraintManager() override
Definition: SimpleConstraintManager.cpp:23
clang::ento::SValBuilder
Definition: SValBuilder.h:53
clang::ASTContext::VoidPtrTy
CanQualType VoidPtrTy
Definition: ASTContext.h:1107
clang::ento::SValBuilder::evalCast
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
Definition: SValBuilder.cpp:1092
clang::ento::SimpleConstraintManager::assumeSymInclusiveRange
virtual ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange)=0
Given a symbolic expression within the range [From, To], assume that it is true/false and generate th...
Value
Value
Definition: UninitializedValues.cpp:103
clang::ento::SimpleConstraintManager::assumeSym
virtual ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym, bool Assumption)=0
Given a symbolic expression that can be reasoned about, assume that it is true/false and generate the...
State
LineState State
Definition: UnwrappedLineFormatter.cpp:1147
APSIntType.h
ProgramState.h
ExprEngine.h
clang
Definition: CalledOnceCheck.h:17
clang::ento::TypedRegion
TypedRegion - An abstract class representing regions that are typed.
Definition: MemRegion.h:507
clang::ento::ExprEngine::processAssume
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption)
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
Definition: ExprEngine.cpp:662
clang::ASTContext::BoolTy
CanQualType BoolTy
Definition: ASTContext.h:1081
clang::ento::SimpleConstraintManager::assumeInternal
ProgramStateRef assumeInternal(ProgramStateRef State, DefinedSVal Cond, bool Assumption) override
Ensures that the DefinedSVal conditional is expressed as a NonLoc by creating boolean casts to handle...
Definition: SimpleConstraintManager.cpp:25
llvm::IntrusiveRefCntPtr< const ProgramState >