1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h" |
15 | #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" |
16 | #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" |
17 | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" |
18 | |
19 | namespace clang { |
20 | |
21 | namespace ento { |
22 | |
23 | SimpleConstraintManager::~SimpleConstraintManager() {} |
24 | |
25 | ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State, |
26 | DefinedSVal Cond, |
27 | bool Assumption) { |
28 | |
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 (NotifyAssumeClients && SU) |
48 | return SU->processAssume(State, Cond, Assumption); |
49 | return State; |
50 | } |
51 | |
52 | ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State, |
53 | NonLoc Cond, |
54 | bool Assumption) { |
55 | |
56 | |
57 | |
58 | if (!canReasonAbout(Cond)) { |
59 | |
60 | SymbolRef Sym = Cond.getAsSymExpr(); |
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 assume(State, Cond.castAs<nonloc::LocAsInteger>().getLoc(), |
90 | Assumption); |
91 | } |
92 | } |
93 | |
94 | ProgramStateRef SimpleConstraintManager::assumeInclusiveRange( |
95 | ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, |
96 | const llvm::APSInt &To, bool InRange) { |
97 | |
98 | (0) . __assert_fail ("From.isUnsigned() == To.isUnsigned() && From.getBitWidth() == To.getBitWidth() && \"Values should have same types!\"", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(From.isUnsigned() == To.isUnsigned() && |
99 | (0) . __assert_fail ("From.isUnsigned() == To.isUnsigned() && From.getBitWidth() == To.getBitWidth() && \"Values should have same types!\"", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> From.getBitWidth() == To.getBitWidth() && |
100 | (0) . __assert_fail ("From.isUnsigned() == To.isUnsigned() && From.getBitWidth() == To.getBitWidth() && \"Values should have same types!\"", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Values should have same types!"); |
101 | |
102 | if (!canReasonAbout(Value)) { |
103 | |
104 | SymbolRef Sym = Value.getAsSymExpr(); |
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 | } |
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 | } |
128 | } |
129 | |
130 | } |
131 | |
132 | } |
133 | |