blob: 7c246e4d2792cac4f488422820e4cc8ef771ef59 [file] [log] [blame]
Ted Kremenek45021952009-02-14 17:08:39 +00001//== SimpleConstraintManager.cpp --------------------------------*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines SimpleConstraintManager, a class that holds code shared
11// between BasicConstraintManager and RangeConstraintManager.
12//
13//===----------------------------------------------------------------------===//
14
15#include "SimpleConstraintManager.h"
Argyrios Kyrtzidis98cabba2010-12-22 18:51:49 +000016#include "clang/GR/PathSensitive/GRExprEngine.h"
17#include "clang/GR/PathSensitive/GRState.h"
18#include "clang/GR/PathSensitive/Checker.h"
Ted Kremenek45021952009-02-14 17:08:39 +000019
20namespace clang {
21
22SimpleConstraintManager::~SimpleConstraintManager() {}
23
Ted Kremenek66b52712009-03-11 02:22:59 +000024bool SimpleConstraintManager::canReasonAbout(SVal X) const {
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000025 if (nonloc::SymExprVal *SymVal = dyn_cast<nonloc::SymExprVal>(&X)) {
26 const SymExpr *SE = SymVal->getSymbolicExpression();
Mike Stump1eb44332009-09-09 15:08:12 +000027
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000028 if (isa<SymbolData>(SE))
29 return true;
Mike Stump1eb44332009-09-09 15:08:12 +000030
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000031 if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
32 switch (SIE->getOpcode()) {
33 // We don't reason yet about bitwise-constraints on symbolic values.
John McCall2de56d12010-08-25 11:45:40 +000034 case BO_And:
35 case BO_Or:
36 case BO_Xor:
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000037 return false;
Jordy Roseba0f61c2010-06-18 22:49:11 +000038 // We don't reason yet about these arithmetic constraints on
39 // symbolic values.
John McCall2de56d12010-08-25 11:45:40 +000040 case BO_Mul:
41 case BO_Div:
42 case BO_Rem:
43 case BO_Shl:
44 case BO_Shr:
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000045 return false;
46 // All other cases.
47 default:
48 return true;
Mike Stump1eb44332009-09-09 15:08:12 +000049 }
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000050 }
51
52 return false;
Ted Kremenek7de20fe2009-03-11 02:29:48 +000053 }
54
Ted Kremenek66b52712009-03-11 02:22:59 +000055 return true;
56}
Mike Stump1eb44332009-09-09 15:08:12 +000057
Ted Kremenek28f47b92010-12-01 22:16:56 +000058const GRState *SimpleConstraintManager::assume(const GRState *state,
Ted Kremenek5b9bd212009-09-11 22:07:28 +000059 DefinedSVal Cond,
60 bool Assumption) {
Ted Kremenek45021952009-02-14 17:08:39 +000061 if (isa<NonLoc>(Cond))
Ted Kremenek28f47b92010-12-01 22:16:56 +000062 return assume(state, cast<NonLoc>(Cond), Assumption);
Ted Kremenek45021952009-02-14 17:08:39 +000063 else
Ted Kremenek28f47b92010-12-01 22:16:56 +000064 return assume(state, cast<Loc>(Cond), Assumption);
Ted Kremenek45021952009-02-14 17:08:39 +000065}
66
Ted Kremenek28f47b92010-12-01 22:16:56 +000067const GRState *SimpleConstraintManager::assume(const GRState *state, Loc cond,
Ted Kremenek32a58082010-01-05 00:15:18 +000068 bool assumption) {
Ted Kremenek28f47b92010-12-01 22:16:56 +000069 state = assumeAux(state, cond, assumption);
Ted Kremenek32a58082010-01-05 00:15:18 +000070 return SU.ProcessAssume(state, cond, assumption);
Ted Kremenek45021952009-02-14 17:08:39 +000071}
72
Ted Kremenek28f47b92010-12-01 22:16:56 +000073const GRState *SimpleConstraintManager::assumeAux(const GRState *state,
Ted Kremeneka591bc02009-06-18 22:57:13 +000074 Loc Cond, bool Assumption) {
Mike Stump1eb44332009-09-09 15:08:12 +000075
Ted Kremeneka591bc02009-06-18 22:57:13 +000076 BasicValueFactory &BasicVals = state->getBasicVals();
Ted Kremenek45021952009-02-14 17:08:39 +000077
78 switch (Cond.getSubKind()) {
79 default:
80 assert (false && "'Assume' not implemented for this Loc.");
Ted Kremeneka591bc02009-06-18 22:57:13 +000081 return state;
Ted Kremenek45021952009-02-14 17:08:39 +000082
Ted Kremenek45021952009-02-14 17:08:39 +000083 case loc::MemRegionKind: {
84 // FIXME: Should this go into the storemanager?
Mike Stump1eb44332009-09-09 15:08:12 +000085
Ted Kremeneka591bc02009-06-18 22:57:13 +000086 const MemRegion *R = cast<loc::MemRegionVal>(Cond).getRegion();
87 const SubRegion *SubR = dyn_cast<SubRegion>(R);
Ted Kremenek45021952009-02-14 17:08:39 +000088
89 while (SubR) {
90 // FIXME: now we only find the first symbolic region.
Ted Kremeneka591bc02009-06-18 22:57:13 +000091 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000092 const llvm::APSInt &zero = BasicVals.getZeroWithPtrWidth();
Zhongxing Xu3330dcb2009-04-10 06:06:13 +000093 if (Assumption)
Ted Kremenek28f47b92010-12-01 22:16:56 +000094 return assumeSymNE(state, SymR->getSymbol(), zero, zero);
Zhongxing Xu3330dcb2009-04-10 06:06:13 +000095 else
Ted Kremenek28f47b92010-12-01 22:16:56 +000096 return assumeSymEQ(state, SymR->getSymbol(), zero, zero);
Zhongxing Xu3330dcb2009-04-10 06:06:13 +000097 }
Ted Kremenek45021952009-02-14 17:08:39 +000098 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
99 }
Mike Stump1eb44332009-09-09 15:08:12 +0000100
Ted Kremenek45021952009-02-14 17:08:39 +0000101 // FALL-THROUGH.
102 }
Mike Stump1eb44332009-09-09 15:08:12 +0000103
Ted Kremenek45021952009-02-14 17:08:39 +0000104 case loc::GotoLabelKind:
Ted Kremeneka591bc02009-06-18 22:57:13 +0000105 return Assumption ? state : NULL;
Ted Kremenek45021952009-02-14 17:08:39 +0000106
107 case loc::ConcreteIntKind: {
Mike Stump1eb44332009-09-09 15:08:12 +0000108 bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
Ted Kremeneka591bc02009-06-18 22:57:13 +0000109 bool isFeasible = b ? Assumption : !Assumption;
110 return isFeasible ? state : NULL;
Ted Kremenek45021952009-02-14 17:08:39 +0000111 }
112 } // end switch
113}
114
Ted Kremenek28f47b92010-12-01 22:16:56 +0000115const GRState *SimpleConstraintManager::assume(const GRState *state,
Ted Kremenek32a58082010-01-05 00:15:18 +0000116 NonLoc cond,
117 bool assumption) {
Ted Kremenek28f47b92010-12-01 22:16:56 +0000118 state = assumeAux(state, cond, assumption);
Ted Kremenek32a58082010-01-05 00:15:18 +0000119 return SU.ProcessAssume(state, cond, assumption);
Ted Kremenek45021952009-02-14 17:08:39 +0000120}
121
Jordy Roseba0f61c2010-06-18 22:49:11 +0000122static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
123 // FIXME: This should probably be part of BinaryOperator, since this isn't
Ted Kremenek846eabd2010-12-01 21:28:31 +0000124 // the only place it's used. (This code was copied from SimpleSValBuilder.cpp.)
Jordy Roseba0f61c2010-06-18 22:49:11 +0000125 switch (op) {
126 default:
127 assert(false && "Invalid opcode.");
John McCall2de56d12010-08-25 11:45:40 +0000128 case BO_LT: return BO_GE;
129 case BO_GT: return BO_LE;
130 case BO_LE: return BO_GT;
131 case BO_GE: return BO_LT;
132 case BO_EQ: return BO_NE;
133 case BO_NE: return BO_EQ;
Jordy Roseba0f61c2010-06-18 22:49:11 +0000134 }
135}
136
Ted Kremenek28f47b92010-12-01 22:16:56 +0000137const GRState *SimpleConstraintManager::assumeAux(const GRState *state,
Ted Kremeneka591bc02009-06-18 22:57:13 +0000138 NonLoc Cond,
139 bool Assumption) {
Mike Stump1eb44332009-09-09 15:08:12 +0000140
Jordy Roseba0f61c2010-06-18 22:49:11 +0000141 // We cannot reason about SymSymExprs,
142 // and can only reason about some SymIntExprs.
Zhongxing Xua129eb92009-03-25 05:58:37 +0000143 if (!canReasonAbout(Cond)) {
Ted Kremeneka591bc02009-06-18 22:57:13 +0000144 // Just return the current state indicating that the path is feasible.
145 // This may be an over-approximation of what is possible.
146 return state;
Mike Stump1eb44332009-09-09 15:08:12 +0000147 }
Zhongxing Xua129eb92009-03-25 05:58:37 +0000148
Ted Kremeneka591bc02009-06-18 22:57:13 +0000149 BasicValueFactory &BasicVals = state->getBasicVals();
150 SymbolManager &SymMgr = state->getSymbolManager();
Ted Kremenek45021952009-02-14 17:08:39 +0000151
152 switch (Cond.getSubKind()) {
153 default:
154 assert(false && "'Assume' not implemented for this NonLoc");
155
156 case nonloc::SymbolValKind: {
157 nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
158 SymbolRef sym = SV.getSymbol();
Mike Stump1eb44332009-09-09 15:08:12 +0000159 QualType T = SymMgr.getType(sym);
Ted Kremeneka591bc02009-06-18 22:57:13 +0000160 const llvm::APSInt &zero = BasicVals.getValue(0, T);
Jordy Roseba0f61c2010-06-18 22:49:11 +0000161 if (Assumption)
Ted Kremenek28f47b92010-12-01 22:16:56 +0000162 return assumeSymNE(state, sym, zero, zero);
Jordy Roseba0f61c2010-06-18 22:49:11 +0000163 else
Ted Kremenek28f47b92010-12-01 22:16:56 +0000164 return assumeSymEQ(state, sym, zero, zero);
Ted Kremenek45021952009-02-14 17:08:39 +0000165 }
166
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000167 case nonloc::SymExprValKind: {
168 nonloc::SymExprVal V = cast<nonloc::SymExprVal>(Cond);
Ted Kremenek80417472009-09-25 00:18:15 +0000169
Jordy Roseba0f61c2010-06-18 22:49:11 +0000170 // For now, we only handle expressions whose RHS is an integer.
171 // All other expressions are assumed to be feasible.
172 const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression());
173 if (!SE)
174 return state;
Mike Stump1eb44332009-09-09 15:08:12 +0000175
Jordy Roseba0f61c2010-06-18 22:49:11 +0000176 BinaryOperator::Opcode op = SE->getOpcode();
Jordy Rose5ca129c2010-06-27 01:20:56 +0000177 // Implicitly compare non-comparison expressions to 0.
178 if (!BinaryOperator::isComparisonOp(op)) {
179 QualType T = SymMgr.getType(SE);
180 const llvm::APSInt &zero = BasicVals.getValue(0, T);
John McCall2de56d12010-08-25 11:45:40 +0000181 op = (Assumption ? BO_NE : BO_EQ);
Ted Kremenek28f47b92010-12-01 22:16:56 +0000182 return assumeSymRel(state, SE, op, zero);
Jordy Rose5ca129c2010-06-27 01:20:56 +0000183 }
Jordy Roseba0f61c2010-06-18 22:49:11 +0000184
185 // From here on out, op is the real comparison we'll be testing.
186 if (!Assumption)
187 op = NegateComparison(op);
188
Ted Kremenek28f47b92010-12-01 22:16:56 +0000189 return assumeSymRel(state, SE->getLHS(), op, SE->getRHS());
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000190 }
Ted Kremenek45021952009-02-14 17:08:39 +0000191
192 case nonloc::ConcreteIntKind: {
193 bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
Ted Kremeneka591bc02009-06-18 22:57:13 +0000194 bool isFeasible = b ? Assumption : !Assumption;
195 return isFeasible ? state : NULL;
Ted Kremenek45021952009-02-14 17:08:39 +0000196 }
197
198 case nonloc::LocAsIntegerKind:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000199 return assumeAux(state, cast<nonloc::LocAsInteger>(Cond).getLoc(),
Ted Kremeneka591bc02009-06-18 22:57:13 +0000200 Assumption);
Ted Kremenek45021952009-02-14 17:08:39 +0000201 } // end switch
202}
203
Ted Kremenek28f47b92010-12-01 22:16:56 +0000204const GRState *SimpleConstraintManager::assumeSymRel(const GRState *state,
Jordy Roseba0f61c2010-06-18 22:49:11 +0000205 const SymExpr *LHS,
206 BinaryOperator::Opcode op,
207 const llvm::APSInt& Int) {
208 assert(BinaryOperator::isComparisonOp(op) &&
209 "Non-comparison ops should be rewritten as comparisons to zero.");
Ted Kremenek45021952009-02-14 17:08:39 +0000210
Jordy Roseba0f61c2010-06-18 22:49:11 +0000211 // We only handle simple comparisons of the form "$sym == constant"
212 // or "($sym+constant1) == constant2".
213 // The adjustment is "constant1" in the above expression. It's used to
214 // "slide" the solution range around for modular arithmetic. For example,
215 // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
216 // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
217 // the subclasses of SimpleConstraintManager to handle the adjustment.
Jordy Roseb4954a42010-06-21 20:15:15 +0000218 llvm::APSInt Adjustment;
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000219
Jordy Roseba0f61c2010-06-18 22:49:11 +0000220 // First check if the LHS is a simple symbol reference.
221 SymbolRef Sym = dyn_cast<SymbolData>(LHS);
Jordy Roseb4954a42010-06-21 20:15:15 +0000222 if (Sym) {
223 Adjustment = 0;
224 } else {
Jordy Roseba0f61c2010-06-18 22:49:11 +0000225 // Next, see if it's a "($sym+constant1)" expression.
226 const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS);
Mike Stump1eb44332009-09-09 15:08:12 +0000227
Jordy Roseba0f61c2010-06-18 22:49:11 +0000228 // We don't handle "($sym1+$sym2)".
229 // Give up and assume the constraint is feasible.
230 if (!SE)
231 return state;
232
233 // We don't handle "(<expr>+constant1)".
234 // Give up and assume the constraint is feasible.
235 Sym = dyn_cast<SymbolData>(SE->getLHS());
236 if (!Sym)
237 return state;
238
239 // Get the constant out of the expression "($sym+constant1)".
240 switch (SE->getOpcode()) {
John McCall2de56d12010-08-25 11:45:40 +0000241 case BO_Add:
Jordy Roseba0f61c2010-06-18 22:49:11 +0000242 Adjustment = SE->getRHS();
243 break;
John McCall2de56d12010-08-25 11:45:40 +0000244 case BO_Sub:
Jordy Roseba0f61c2010-06-18 22:49:11 +0000245 Adjustment = -SE->getRHS();
246 break;
247 default:
248 // We don't handle non-additive operators.
249 // Give up and assume the constraint is feasible.
250 return state;
251 }
252 }
253
Jordy Roseb4954a42010-06-21 20:15:15 +0000254 // FIXME: This next section is a hack. It silently converts the integers to
255 // be of the same type as the symbol, which is not always correct. Really the
256 // comparisons should be performed using the Int's type, then mapped back to
257 // the symbol's range of values.
258 GRStateManager &StateMgr = state->getStateManager();
259 ASTContext &Ctx = StateMgr.getContext();
260
261 QualType T = Sym->getType(Ctx);
262 assert(T->isIntegerType() || Loc::IsLocType(T));
263 unsigned bitwidth = Ctx.getTypeSize(T);
264 bool isSymUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
265
266 // Convert the adjustment.
267 Adjustment.setIsUnsigned(isSymUnsigned);
Jay Foad9f71a8f2010-12-07 08:25:34 +0000268 Adjustment = Adjustment.extOrTrunc(bitwidth);
Jordy Roseb4954a42010-06-21 20:15:15 +0000269
270 // Convert the right-hand side integer.
271 llvm::APSInt ConvertedInt(Int, isSymUnsigned);
Jay Foad9f71a8f2010-12-07 08:25:34 +0000272 ConvertedInt = ConvertedInt.extOrTrunc(bitwidth);
Jordy Roseb4954a42010-06-21 20:15:15 +0000273
Jordy Roseba0f61c2010-06-18 22:49:11 +0000274 switch (op) {
Ted Kremenek45021952009-02-14 17:08:39 +0000275 default:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000276 // No logic yet for other operators. assume the constraint is feasible.
Ted Kremeneka591bc02009-06-18 22:57:13 +0000277 return state;
Ted Kremenek45021952009-02-14 17:08:39 +0000278
John McCall2de56d12010-08-25 11:45:40 +0000279 case BO_EQ:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000280 return assumeSymEQ(state, Sym, ConvertedInt, Adjustment);
Ted Kremenek45021952009-02-14 17:08:39 +0000281
John McCall2de56d12010-08-25 11:45:40 +0000282 case BO_NE:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000283 return assumeSymNE(state, Sym, ConvertedInt, Adjustment);
Jordy Roseba0f61c2010-06-18 22:49:11 +0000284
John McCall2de56d12010-08-25 11:45:40 +0000285 case BO_GT:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000286 return assumeSymGT(state, Sym, ConvertedInt, Adjustment);
Ted Kremenek45021952009-02-14 17:08:39 +0000287
John McCall2de56d12010-08-25 11:45:40 +0000288 case BO_GE:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000289 return assumeSymGE(state, Sym, ConvertedInt, Adjustment);
Ted Kremenek45021952009-02-14 17:08:39 +0000290
John McCall2de56d12010-08-25 11:45:40 +0000291 case BO_LT:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000292 return assumeSymLT(state, Sym, ConvertedInt, Adjustment);
Mike Stump1eb44332009-09-09 15:08:12 +0000293
John McCall2de56d12010-08-25 11:45:40 +0000294 case BO_LE:
Ted Kremenek28f47b92010-12-01 22:16:56 +0000295 return assumeSymLE(state, Sym, ConvertedInt, Adjustment);
Ted Kremenek45021952009-02-14 17:08:39 +0000296 } // end switch
297}
298
Ted Kremenek45021952009-02-14 17:08:39 +0000299} // end of namespace clang