1*fa0734ecSArgyrios Kyrtzidis // SimpleSValBuilder.cpp - A basic SValBuilder -----------------------*- C++ -*-
2*fa0734ecSArgyrios Kyrtzidis //
3*fa0734ecSArgyrios Kyrtzidis //                     The LLVM Compiler Infrastructure
4*fa0734ecSArgyrios Kyrtzidis //
5*fa0734ecSArgyrios Kyrtzidis // This file is distributed under the University of Illinois Open Source
6*fa0734ecSArgyrios Kyrtzidis // License. See LICENSE.TXT for details.
7*fa0734ecSArgyrios Kyrtzidis //
8*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
9*fa0734ecSArgyrios Kyrtzidis //
10*fa0734ecSArgyrios Kyrtzidis //  This file defines SimpleSValBuilder, a basic implementation of SValBuilder.
11*fa0734ecSArgyrios Kyrtzidis //
12*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
13*fa0734ecSArgyrios Kyrtzidis 
14*fa0734ecSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/PathSensitive/SValBuilder.h"
15*fa0734ecSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/PathSensitive/GRState.h"
16*fa0734ecSArgyrios Kyrtzidis 
17*fa0734ecSArgyrios Kyrtzidis using namespace clang;
18*fa0734ecSArgyrios Kyrtzidis using namespace ento;
19*fa0734ecSArgyrios Kyrtzidis 
20*fa0734ecSArgyrios Kyrtzidis namespace {
21*fa0734ecSArgyrios Kyrtzidis class SimpleSValBuilder : public SValBuilder {
22*fa0734ecSArgyrios Kyrtzidis protected:
23*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalCastNL(NonLoc val, QualType castTy);
24*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalCastL(Loc val, QualType castTy);
25*fa0734ecSArgyrios Kyrtzidis 
26*fa0734ecSArgyrios Kyrtzidis public:
27*fa0734ecSArgyrios Kyrtzidis   SimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
28*fa0734ecSArgyrios Kyrtzidis                     GRStateManager &stateMgr)
29*fa0734ecSArgyrios Kyrtzidis                     : SValBuilder(alloc, context, stateMgr) {}
30*fa0734ecSArgyrios Kyrtzidis   virtual ~SimpleSValBuilder() {}
31*fa0734ecSArgyrios Kyrtzidis 
32*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalMinus(NonLoc val);
33*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalComplement(NonLoc val);
34*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
35*fa0734ecSArgyrios Kyrtzidis                            NonLoc lhs, NonLoc rhs, QualType resultTy);
36*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode op,
37*fa0734ecSArgyrios Kyrtzidis                            Loc lhs, Loc rhs, QualType resultTy);
38*fa0734ecSArgyrios Kyrtzidis   virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
39*fa0734ecSArgyrios Kyrtzidis                            Loc lhs, NonLoc rhs, QualType resultTy);
40*fa0734ecSArgyrios Kyrtzidis 
41*fa0734ecSArgyrios Kyrtzidis   /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
42*fa0734ecSArgyrios Kyrtzidis   ///  (integer) value, that value is returned. Otherwise, returns NULL.
43*fa0734ecSArgyrios Kyrtzidis   virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V);
44*fa0734ecSArgyrios Kyrtzidis 
45*fa0734ecSArgyrios Kyrtzidis   SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
46*fa0734ecSArgyrios Kyrtzidis                      const llvm::APSInt &RHS, QualType resultTy);
47*fa0734ecSArgyrios Kyrtzidis };
48*fa0734ecSArgyrios Kyrtzidis } // end anonymous namespace
49*fa0734ecSArgyrios Kyrtzidis 
50*fa0734ecSArgyrios Kyrtzidis SValBuilder *ento::createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
51*fa0734ecSArgyrios Kyrtzidis                                            ASTContext &context,
52*fa0734ecSArgyrios Kyrtzidis                                            GRStateManager &stateMgr) {
53*fa0734ecSArgyrios Kyrtzidis   return new SimpleSValBuilder(alloc, context, stateMgr);
54*fa0734ecSArgyrios Kyrtzidis }
55*fa0734ecSArgyrios Kyrtzidis 
56*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
57*fa0734ecSArgyrios Kyrtzidis // Transfer function for Casts.
58*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
59*fa0734ecSArgyrios Kyrtzidis 
60*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalCastNL(NonLoc val, QualType castTy) {
61*fa0734ecSArgyrios Kyrtzidis 
62*fa0734ecSArgyrios Kyrtzidis   bool isLocType = Loc::IsLocType(castTy);
63*fa0734ecSArgyrios Kyrtzidis 
64*fa0734ecSArgyrios Kyrtzidis   if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
65*fa0734ecSArgyrios Kyrtzidis     if (isLocType)
66*fa0734ecSArgyrios Kyrtzidis       return LI->getLoc();
67*fa0734ecSArgyrios Kyrtzidis 
68*fa0734ecSArgyrios Kyrtzidis     // FIXME: Correctly support promotions/truncations.
69*fa0734ecSArgyrios Kyrtzidis     unsigned castSize = Context.getTypeSize(castTy);
70*fa0734ecSArgyrios Kyrtzidis     if (castSize == LI->getNumBits())
71*fa0734ecSArgyrios Kyrtzidis       return val;
72*fa0734ecSArgyrios Kyrtzidis     return makeLocAsInteger(LI->getLoc(), castSize);
73*fa0734ecSArgyrios Kyrtzidis   }
74*fa0734ecSArgyrios Kyrtzidis 
75*fa0734ecSArgyrios Kyrtzidis   if (const SymExpr *se = val.getAsSymbolicExpression()) {
76*fa0734ecSArgyrios Kyrtzidis     QualType T = Context.getCanonicalType(se->getType(Context));
77*fa0734ecSArgyrios Kyrtzidis     if (T == Context.getCanonicalType(castTy))
78*fa0734ecSArgyrios Kyrtzidis       return val;
79*fa0734ecSArgyrios Kyrtzidis 
80*fa0734ecSArgyrios Kyrtzidis     // FIXME: Remove this hack when we support symbolic truncation/extension.
81*fa0734ecSArgyrios Kyrtzidis     // HACK: If both castTy and T are integers, ignore the cast.  This is
82*fa0734ecSArgyrios Kyrtzidis     // not a permanent solution.  Eventually we want to precisely handle
83*fa0734ecSArgyrios Kyrtzidis     // extension/truncation of symbolic integers.  This prevents us from losing
84*fa0734ecSArgyrios Kyrtzidis     // precision when we assign 'x = y' and 'y' is symbolic and x and y are
85*fa0734ecSArgyrios Kyrtzidis     // different integer types.
86*fa0734ecSArgyrios Kyrtzidis     if (T->isIntegerType() && castTy->isIntegerType())
87*fa0734ecSArgyrios Kyrtzidis       return val;
88*fa0734ecSArgyrios Kyrtzidis 
89*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
90*fa0734ecSArgyrios Kyrtzidis   }
91*fa0734ecSArgyrios Kyrtzidis 
92*fa0734ecSArgyrios Kyrtzidis   if (!isa<nonloc::ConcreteInt>(val))
93*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
94*fa0734ecSArgyrios Kyrtzidis 
95*fa0734ecSArgyrios Kyrtzidis   // Only handle casts from integers to integers.
96*fa0734ecSArgyrios Kyrtzidis   if (!isLocType && !castTy->isIntegerType())
97*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
98*fa0734ecSArgyrios Kyrtzidis 
99*fa0734ecSArgyrios Kyrtzidis   llvm::APSInt i = cast<nonloc::ConcreteInt>(val).getValue();
100*fa0734ecSArgyrios Kyrtzidis   i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
101*fa0734ecSArgyrios Kyrtzidis   i = i.extOrTrunc(Context.getTypeSize(castTy));
102*fa0734ecSArgyrios Kyrtzidis 
103*fa0734ecSArgyrios Kyrtzidis   if (isLocType)
104*fa0734ecSArgyrios Kyrtzidis     return makeIntLocVal(i);
105*fa0734ecSArgyrios Kyrtzidis   else
106*fa0734ecSArgyrios Kyrtzidis     return makeIntVal(i);
107*fa0734ecSArgyrios Kyrtzidis }
108*fa0734ecSArgyrios Kyrtzidis 
109*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalCastL(Loc val, QualType castTy) {
110*fa0734ecSArgyrios Kyrtzidis 
111*fa0734ecSArgyrios Kyrtzidis   // Casts from pointers -> pointers, just return the lval.
112*fa0734ecSArgyrios Kyrtzidis   //
113*fa0734ecSArgyrios Kyrtzidis   // Casts from pointers -> references, just return the lval.  These
114*fa0734ecSArgyrios Kyrtzidis   //   can be introduced by the frontend for corner cases, e.g
115*fa0734ecSArgyrios Kyrtzidis   //   casting from va_list* to __builtin_va_list&.
116*fa0734ecSArgyrios Kyrtzidis   //
117*fa0734ecSArgyrios Kyrtzidis   if (Loc::IsLocType(castTy) || castTy->isReferenceType())
118*fa0734ecSArgyrios Kyrtzidis     return val;
119*fa0734ecSArgyrios Kyrtzidis 
120*fa0734ecSArgyrios Kyrtzidis   // FIXME: Handle transparent unions where a value can be "transparently"
121*fa0734ecSArgyrios Kyrtzidis   //  lifted into a union type.
122*fa0734ecSArgyrios Kyrtzidis   if (castTy->isUnionType())
123*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
124*fa0734ecSArgyrios Kyrtzidis 
125*fa0734ecSArgyrios Kyrtzidis   if (castTy->isIntegerType()) {
126*fa0734ecSArgyrios Kyrtzidis     unsigned BitWidth = Context.getTypeSize(castTy);
127*fa0734ecSArgyrios Kyrtzidis 
128*fa0734ecSArgyrios Kyrtzidis     if (!isa<loc::ConcreteInt>(val))
129*fa0734ecSArgyrios Kyrtzidis       return makeLocAsInteger(val, BitWidth);
130*fa0734ecSArgyrios Kyrtzidis 
131*fa0734ecSArgyrios Kyrtzidis     llvm::APSInt i = cast<loc::ConcreteInt>(val).getValue();
132*fa0734ecSArgyrios Kyrtzidis     i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
133*fa0734ecSArgyrios Kyrtzidis     i = i.extOrTrunc(BitWidth);
134*fa0734ecSArgyrios Kyrtzidis     return makeIntVal(i);
135*fa0734ecSArgyrios Kyrtzidis   }
136*fa0734ecSArgyrios Kyrtzidis 
137*fa0734ecSArgyrios Kyrtzidis   // All other cases: return 'UnknownVal'.  This includes casting pointers
138*fa0734ecSArgyrios Kyrtzidis   // to floats, which is probably badness it itself, but this is a good
139*fa0734ecSArgyrios Kyrtzidis   // intermediate solution until we do something better.
140*fa0734ecSArgyrios Kyrtzidis   return UnknownVal();
141*fa0734ecSArgyrios Kyrtzidis }
142*fa0734ecSArgyrios Kyrtzidis 
143*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
144*fa0734ecSArgyrios Kyrtzidis // Transfer function for unary operators.
145*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
146*fa0734ecSArgyrios Kyrtzidis 
147*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalMinus(NonLoc val) {
148*fa0734ecSArgyrios Kyrtzidis   switch (val.getSubKind()) {
149*fa0734ecSArgyrios Kyrtzidis   case nonloc::ConcreteIntKind:
150*fa0734ecSArgyrios Kyrtzidis     return cast<nonloc::ConcreteInt>(val).evalMinus(*this);
151*fa0734ecSArgyrios Kyrtzidis   default:
152*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
153*fa0734ecSArgyrios Kyrtzidis   }
154*fa0734ecSArgyrios Kyrtzidis }
155*fa0734ecSArgyrios Kyrtzidis 
156*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalComplement(NonLoc X) {
157*fa0734ecSArgyrios Kyrtzidis   switch (X.getSubKind()) {
158*fa0734ecSArgyrios Kyrtzidis   case nonloc::ConcreteIntKind:
159*fa0734ecSArgyrios Kyrtzidis     return cast<nonloc::ConcreteInt>(X).evalComplement(*this);
160*fa0734ecSArgyrios Kyrtzidis   default:
161*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
162*fa0734ecSArgyrios Kyrtzidis   }
163*fa0734ecSArgyrios Kyrtzidis }
164*fa0734ecSArgyrios Kyrtzidis 
165*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
166*fa0734ecSArgyrios Kyrtzidis // Transfer function for binary operators.
167*fa0734ecSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
168*fa0734ecSArgyrios Kyrtzidis 
169*fa0734ecSArgyrios Kyrtzidis static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
170*fa0734ecSArgyrios Kyrtzidis   switch (op) {
171*fa0734ecSArgyrios Kyrtzidis   default:
172*fa0734ecSArgyrios Kyrtzidis     assert(false && "Invalid opcode.");
173*fa0734ecSArgyrios Kyrtzidis   case BO_LT: return BO_GE;
174*fa0734ecSArgyrios Kyrtzidis   case BO_GT: return BO_LE;
175*fa0734ecSArgyrios Kyrtzidis   case BO_LE: return BO_GT;
176*fa0734ecSArgyrios Kyrtzidis   case BO_GE: return BO_LT;
177*fa0734ecSArgyrios Kyrtzidis   case BO_EQ: return BO_NE;
178*fa0734ecSArgyrios Kyrtzidis   case BO_NE: return BO_EQ;
179*fa0734ecSArgyrios Kyrtzidis   }
180*fa0734ecSArgyrios Kyrtzidis }
181*fa0734ecSArgyrios Kyrtzidis 
182*fa0734ecSArgyrios Kyrtzidis static BinaryOperator::Opcode ReverseComparison(BinaryOperator::Opcode op) {
183*fa0734ecSArgyrios Kyrtzidis   switch (op) {
184*fa0734ecSArgyrios Kyrtzidis   default:
185*fa0734ecSArgyrios Kyrtzidis     assert(false && "Invalid opcode.");
186*fa0734ecSArgyrios Kyrtzidis   case BO_LT: return BO_GT;
187*fa0734ecSArgyrios Kyrtzidis   case BO_GT: return BO_LT;
188*fa0734ecSArgyrios Kyrtzidis   case BO_LE: return BO_GE;
189*fa0734ecSArgyrios Kyrtzidis   case BO_GE: return BO_LE;
190*fa0734ecSArgyrios Kyrtzidis   case BO_EQ:
191*fa0734ecSArgyrios Kyrtzidis   case BO_NE:
192*fa0734ecSArgyrios Kyrtzidis     return op;
193*fa0734ecSArgyrios Kyrtzidis   }
194*fa0734ecSArgyrios Kyrtzidis }
195*fa0734ecSArgyrios Kyrtzidis 
196*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
197*fa0734ecSArgyrios Kyrtzidis                                     BinaryOperator::Opcode op,
198*fa0734ecSArgyrios Kyrtzidis                                     const llvm::APSInt &RHS,
199*fa0734ecSArgyrios Kyrtzidis                                     QualType resultTy) {
200*fa0734ecSArgyrios Kyrtzidis   bool isIdempotent = false;
201*fa0734ecSArgyrios Kyrtzidis 
202*fa0734ecSArgyrios Kyrtzidis   // Check for a few special cases with known reductions first.
203*fa0734ecSArgyrios Kyrtzidis   switch (op) {
204*fa0734ecSArgyrios Kyrtzidis   default:
205*fa0734ecSArgyrios Kyrtzidis     // We can't reduce this case; just treat it normally.
206*fa0734ecSArgyrios Kyrtzidis     break;
207*fa0734ecSArgyrios Kyrtzidis   case BO_Mul:
208*fa0734ecSArgyrios Kyrtzidis     // a*0 and a*1
209*fa0734ecSArgyrios Kyrtzidis     if (RHS == 0)
210*fa0734ecSArgyrios Kyrtzidis       return makeIntVal(0, resultTy);
211*fa0734ecSArgyrios Kyrtzidis     else if (RHS == 1)
212*fa0734ecSArgyrios Kyrtzidis       isIdempotent = true;
213*fa0734ecSArgyrios Kyrtzidis     break;
214*fa0734ecSArgyrios Kyrtzidis   case BO_Div:
215*fa0734ecSArgyrios Kyrtzidis     // a/0 and a/1
216*fa0734ecSArgyrios Kyrtzidis     if (RHS == 0)
217*fa0734ecSArgyrios Kyrtzidis       // This is also handled elsewhere.
218*fa0734ecSArgyrios Kyrtzidis       return UndefinedVal();
219*fa0734ecSArgyrios Kyrtzidis     else if (RHS == 1)
220*fa0734ecSArgyrios Kyrtzidis       isIdempotent = true;
221*fa0734ecSArgyrios Kyrtzidis     break;
222*fa0734ecSArgyrios Kyrtzidis   case BO_Rem:
223*fa0734ecSArgyrios Kyrtzidis     // a%0 and a%1
224*fa0734ecSArgyrios Kyrtzidis     if (RHS == 0)
225*fa0734ecSArgyrios Kyrtzidis       // This is also handled elsewhere.
226*fa0734ecSArgyrios Kyrtzidis       return UndefinedVal();
227*fa0734ecSArgyrios Kyrtzidis     else if (RHS == 1)
228*fa0734ecSArgyrios Kyrtzidis       return makeIntVal(0, resultTy);
229*fa0734ecSArgyrios Kyrtzidis     break;
230*fa0734ecSArgyrios Kyrtzidis   case BO_Add:
231*fa0734ecSArgyrios Kyrtzidis   case BO_Sub:
232*fa0734ecSArgyrios Kyrtzidis   case BO_Shl:
233*fa0734ecSArgyrios Kyrtzidis   case BO_Shr:
234*fa0734ecSArgyrios Kyrtzidis   case BO_Xor:
235*fa0734ecSArgyrios Kyrtzidis     // a+0, a-0, a<<0, a>>0, a^0
236*fa0734ecSArgyrios Kyrtzidis     if (RHS == 0)
237*fa0734ecSArgyrios Kyrtzidis       isIdempotent = true;
238*fa0734ecSArgyrios Kyrtzidis     break;
239*fa0734ecSArgyrios Kyrtzidis   case BO_And:
240*fa0734ecSArgyrios Kyrtzidis     // a&0 and a&(~0)
241*fa0734ecSArgyrios Kyrtzidis     if (RHS == 0)
242*fa0734ecSArgyrios Kyrtzidis       return makeIntVal(0, resultTy);
243*fa0734ecSArgyrios Kyrtzidis     else if (RHS.isAllOnesValue())
244*fa0734ecSArgyrios Kyrtzidis       isIdempotent = true;
245*fa0734ecSArgyrios Kyrtzidis     break;
246*fa0734ecSArgyrios Kyrtzidis   case BO_Or:
247*fa0734ecSArgyrios Kyrtzidis     // a|0 and a|(~0)
248*fa0734ecSArgyrios Kyrtzidis     if (RHS == 0)
249*fa0734ecSArgyrios Kyrtzidis       isIdempotent = true;
250*fa0734ecSArgyrios Kyrtzidis     else if (RHS.isAllOnesValue()) {
251*fa0734ecSArgyrios Kyrtzidis       const llvm::APSInt &Result = BasicVals.Convert(resultTy, RHS);
252*fa0734ecSArgyrios Kyrtzidis       return nonloc::ConcreteInt(Result);
253*fa0734ecSArgyrios Kyrtzidis     }
254*fa0734ecSArgyrios Kyrtzidis     break;
255*fa0734ecSArgyrios Kyrtzidis   }
256*fa0734ecSArgyrios Kyrtzidis 
257*fa0734ecSArgyrios Kyrtzidis   // Idempotent ops (like a*1) can still change the type of an expression.
258*fa0734ecSArgyrios Kyrtzidis   // Wrap the LHS up in a NonLoc again and let evalCastNL do the dirty work.
259*fa0734ecSArgyrios Kyrtzidis   if (isIdempotent) {
260*fa0734ecSArgyrios Kyrtzidis     if (SymbolRef LHSSym = dyn_cast<SymbolData>(LHS))
261*fa0734ecSArgyrios Kyrtzidis       return evalCastNL(nonloc::SymbolVal(LHSSym), resultTy);
262*fa0734ecSArgyrios Kyrtzidis     return evalCastNL(nonloc::SymExprVal(LHS), resultTy);
263*fa0734ecSArgyrios Kyrtzidis   }
264*fa0734ecSArgyrios Kyrtzidis 
265*fa0734ecSArgyrios Kyrtzidis   // If we reach this point, the expression cannot be simplified.
266*fa0734ecSArgyrios Kyrtzidis   // Make a SymExprVal for the entire thing.
267*fa0734ecSArgyrios Kyrtzidis   return makeNonLoc(LHS, op, RHS, resultTy);
268*fa0734ecSArgyrios Kyrtzidis }
269*fa0734ecSArgyrios Kyrtzidis 
270*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalBinOpNN(const GRState *state,
271*fa0734ecSArgyrios Kyrtzidis                                   BinaryOperator::Opcode op,
272*fa0734ecSArgyrios Kyrtzidis                                   NonLoc lhs, NonLoc rhs,
273*fa0734ecSArgyrios Kyrtzidis                                   QualType resultTy)  {
274*fa0734ecSArgyrios Kyrtzidis   // Handle trivial case where left-side and right-side are the same.
275*fa0734ecSArgyrios Kyrtzidis   if (lhs == rhs)
276*fa0734ecSArgyrios Kyrtzidis     switch (op) {
277*fa0734ecSArgyrios Kyrtzidis       default:
278*fa0734ecSArgyrios Kyrtzidis         break;
279*fa0734ecSArgyrios Kyrtzidis       case BO_EQ:
280*fa0734ecSArgyrios Kyrtzidis       case BO_LE:
281*fa0734ecSArgyrios Kyrtzidis       case BO_GE:
282*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(true, resultTy);
283*fa0734ecSArgyrios Kyrtzidis       case BO_LT:
284*fa0734ecSArgyrios Kyrtzidis       case BO_GT:
285*fa0734ecSArgyrios Kyrtzidis       case BO_NE:
286*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(false, resultTy);
287*fa0734ecSArgyrios Kyrtzidis       case BO_Xor:
288*fa0734ecSArgyrios Kyrtzidis       case BO_Sub:
289*fa0734ecSArgyrios Kyrtzidis         return makeIntVal(0, resultTy);
290*fa0734ecSArgyrios Kyrtzidis       case BO_Or:
291*fa0734ecSArgyrios Kyrtzidis       case BO_And:
292*fa0734ecSArgyrios Kyrtzidis         return evalCastNL(lhs, resultTy);
293*fa0734ecSArgyrios Kyrtzidis     }
294*fa0734ecSArgyrios Kyrtzidis 
295*fa0734ecSArgyrios Kyrtzidis   while (1) {
296*fa0734ecSArgyrios Kyrtzidis     switch (lhs.getSubKind()) {
297*fa0734ecSArgyrios Kyrtzidis     default:
298*fa0734ecSArgyrios Kyrtzidis       return UnknownVal();
299*fa0734ecSArgyrios Kyrtzidis     case nonloc::LocAsIntegerKind: {
300*fa0734ecSArgyrios Kyrtzidis       Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
301*fa0734ecSArgyrios Kyrtzidis       switch (rhs.getSubKind()) {
302*fa0734ecSArgyrios Kyrtzidis         case nonloc::LocAsIntegerKind:
303*fa0734ecSArgyrios Kyrtzidis           return evalBinOpLL(state, op, lhsL,
304*fa0734ecSArgyrios Kyrtzidis                              cast<nonloc::LocAsInteger>(rhs).getLoc(),
305*fa0734ecSArgyrios Kyrtzidis                              resultTy);
306*fa0734ecSArgyrios Kyrtzidis         case nonloc::ConcreteIntKind: {
307*fa0734ecSArgyrios Kyrtzidis           // Transform the integer into a location and compare.
308*fa0734ecSArgyrios Kyrtzidis           llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue();
309*fa0734ecSArgyrios Kyrtzidis           i.setIsUnsigned(true);
310*fa0734ecSArgyrios Kyrtzidis           i = i.extOrTrunc(Context.getTypeSize(Context.VoidPtrTy));
311*fa0734ecSArgyrios Kyrtzidis           return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
312*fa0734ecSArgyrios Kyrtzidis         }
313*fa0734ecSArgyrios Kyrtzidis         default:
314*fa0734ecSArgyrios Kyrtzidis           switch (op) {
315*fa0734ecSArgyrios Kyrtzidis             case BO_EQ:
316*fa0734ecSArgyrios Kyrtzidis               return makeTruthVal(false, resultTy);
317*fa0734ecSArgyrios Kyrtzidis             case BO_NE:
318*fa0734ecSArgyrios Kyrtzidis               return makeTruthVal(true, resultTy);
319*fa0734ecSArgyrios Kyrtzidis             default:
320*fa0734ecSArgyrios Kyrtzidis               // This case also handles pointer arithmetic.
321*fa0734ecSArgyrios Kyrtzidis               return UnknownVal();
322*fa0734ecSArgyrios Kyrtzidis           }
323*fa0734ecSArgyrios Kyrtzidis       }
324*fa0734ecSArgyrios Kyrtzidis     }
325*fa0734ecSArgyrios Kyrtzidis     case nonloc::SymExprValKind: {
326*fa0734ecSArgyrios Kyrtzidis       nonloc::SymExprVal *selhs = cast<nonloc::SymExprVal>(&lhs);
327*fa0734ecSArgyrios Kyrtzidis 
328*fa0734ecSArgyrios Kyrtzidis       // Only handle LHS of the form "$sym op constant", at least for now.
329*fa0734ecSArgyrios Kyrtzidis       const SymIntExpr *symIntExpr =
330*fa0734ecSArgyrios Kyrtzidis         dyn_cast<SymIntExpr>(selhs->getSymbolicExpression());
331*fa0734ecSArgyrios Kyrtzidis 
332*fa0734ecSArgyrios Kyrtzidis       if (!symIntExpr)
333*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
334*fa0734ecSArgyrios Kyrtzidis 
335*fa0734ecSArgyrios Kyrtzidis       // Is this a logical not? (!x is represented as x == 0.)
336*fa0734ecSArgyrios Kyrtzidis       if (op == BO_EQ && rhs.isZeroConstant()) {
337*fa0734ecSArgyrios Kyrtzidis         // We know how to negate certain expressions. Simplify them here.
338*fa0734ecSArgyrios Kyrtzidis 
339*fa0734ecSArgyrios Kyrtzidis         BinaryOperator::Opcode opc = symIntExpr->getOpcode();
340*fa0734ecSArgyrios Kyrtzidis         switch (opc) {
341*fa0734ecSArgyrios Kyrtzidis         default:
342*fa0734ecSArgyrios Kyrtzidis           // We don't know how to negate this operation.
343*fa0734ecSArgyrios Kyrtzidis           // Just handle it as if it were a normal comparison to 0.
344*fa0734ecSArgyrios Kyrtzidis           break;
345*fa0734ecSArgyrios Kyrtzidis         case BO_LAnd:
346*fa0734ecSArgyrios Kyrtzidis         case BO_LOr:
347*fa0734ecSArgyrios Kyrtzidis           assert(false && "Logical operators handled by branching logic.");
348*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
349*fa0734ecSArgyrios Kyrtzidis         case BO_Assign:
350*fa0734ecSArgyrios Kyrtzidis         case BO_MulAssign:
351*fa0734ecSArgyrios Kyrtzidis         case BO_DivAssign:
352*fa0734ecSArgyrios Kyrtzidis         case BO_RemAssign:
353*fa0734ecSArgyrios Kyrtzidis         case BO_AddAssign:
354*fa0734ecSArgyrios Kyrtzidis         case BO_SubAssign:
355*fa0734ecSArgyrios Kyrtzidis         case BO_ShlAssign:
356*fa0734ecSArgyrios Kyrtzidis         case BO_ShrAssign:
357*fa0734ecSArgyrios Kyrtzidis         case BO_AndAssign:
358*fa0734ecSArgyrios Kyrtzidis         case BO_XorAssign:
359*fa0734ecSArgyrios Kyrtzidis         case BO_OrAssign:
360*fa0734ecSArgyrios Kyrtzidis         case BO_Comma:
361*fa0734ecSArgyrios Kyrtzidis           assert(false && "'=' and ',' operators handled by ExprEngine.");
362*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
363*fa0734ecSArgyrios Kyrtzidis         case BO_PtrMemD:
364*fa0734ecSArgyrios Kyrtzidis         case BO_PtrMemI:
365*fa0734ecSArgyrios Kyrtzidis           assert(false && "Pointer arithmetic not handled here.");
366*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
367*fa0734ecSArgyrios Kyrtzidis         case BO_LT:
368*fa0734ecSArgyrios Kyrtzidis         case BO_GT:
369*fa0734ecSArgyrios Kyrtzidis         case BO_LE:
370*fa0734ecSArgyrios Kyrtzidis         case BO_GE:
371*fa0734ecSArgyrios Kyrtzidis         case BO_EQ:
372*fa0734ecSArgyrios Kyrtzidis         case BO_NE:
373*fa0734ecSArgyrios Kyrtzidis           // Negate the comparison and make a value.
374*fa0734ecSArgyrios Kyrtzidis           opc = NegateComparison(opc);
375*fa0734ecSArgyrios Kyrtzidis           assert(symIntExpr->getType(Context) == resultTy);
376*fa0734ecSArgyrios Kyrtzidis           return makeNonLoc(symIntExpr->getLHS(), opc,
377*fa0734ecSArgyrios Kyrtzidis                                    symIntExpr->getRHS(), resultTy);
378*fa0734ecSArgyrios Kyrtzidis         }
379*fa0734ecSArgyrios Kyrtzidis       }
380*fa0734ecSArgyrios Kyrtzidis 
381*fa0734ecSArgyrios Kyrtzidis       // For now, only handle expressions whose RHS is a constant.
382*fa0734ecSArgyrios Kyrtzidis       const nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs);
383*fa0734ecSArgyrios Kyrtzidis       if (!rhsInt)
384*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
385*fa0734ecSArgyrios Kyrtzidis 
386*fa0734ecSArgyrios Kyrtzidis       // If both the LHS and the current expression are additive,
387*fa0734ecSArgyrios Kyrtzidis       // fold their constants.
388*fa0734ecSArgyrios Kyrtzidis       if (BinaryOperator::isAdditiveOp(op)) {
389*fa0734ecSArgyrios Kyrtzidis         BinaryOperator::Opcode lop = symIntExpr->getOpcode();
390*fa0734ecSArgyrios Kyrtzidis         if (BinaryOperator::isAdditiveOp(lop)) {
391*fa0734ecSArgyrios Kyrtzidis           // resultTy may not be the best type to convert to, but it's
392*fa0734ecSArgyrios Kyrtzidis           // probably the best choice in expressions with mixed type
393*fa0734ecSArgyrios Kyrtzidis           // (such as x+1U+2LL). The rules for implicit conversions should
394*fa0734ecSArgyrios Kyrtzidis           // choose a reasonable type to preserve the expression, and will
395*fa0734ecSArgyrios Kyrtzidis           // at least match how the value is going to be used.
396*fa0734ecSArgyrios Kyrtzidis           const llvm::APSInt &first =
397*fa0734ecSArgyrios Kyrtzidis             BasicVals.Convert(resultTy, symIntExpr->getRHS());
398*fa0734ecSArgyrios Kyrtzidis           const llvm::APSInt &second =
399*fa0734ecSArgyrios Kyrtzidis             BasicVals.Convert(resultTy, rhsInt->getValue());
400*fa0734ecSArgyrios Kyrtzidis           const llvm::APSInt *newRHS;
401*fa0734ecSArgyrios Kyrtzidis           if (lop == op)
402*fa0734ecSArgyrios Kyrtzidis             newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
403*fa0734ecSArgyrios Kyrtzidis           else
404*fa0734ecSArgyrios Kyrtzidis             newRHS = BasicVals.evalAPSInt(BO_Sub, first, second);
405*fa0734ecSArgyrios Kyrtzidis           return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy);
406*fa0734ecSArgyrios Kyrtzidis         }
407*fa0734ecSArgyrios Kyrtzidis       }
408*fa0734ecSArgyrios Kyrtzidis 
409*fa0734ecSArgyrios Kyrtzidis       // Otherwise, make a SymExprVal out of the expression.
410*fa0734ecSArgyrios Kyrtzidis       return MakeSymIntVal(symIntExpr, op, rhsInt->getValue(), resultTy);
411*fa0734ecSArgyrios Kyrtzidis     }
412*fa0734ecSArgyrios Kyrtzidis     case nonloc::ConcreteIntKind: {
413*fa0734ecSArgyrios Kyrtzidis       const nonloc::ConcreteInt& lhsInt = cast<nonloc::ConcreteInt>(lhs);
414*fa0734ecSArgyrios Kyrtzidis 
415*fa0734ecSArgyrios Kyrtzidis       if (isa<nonloc::ConcreteInt>(rhs)) {
416*fa0734ecSArgyrios Kyrtzidis         return lhsInt.evalBinOp(*this, op, cast<nonloc::ConcreteInt>(rhs));
417*fa0734ecSArgyrios Kyrtzidis       } else {
418*fa0734ecSArgyrios Kyrtzidis         const llvm::APSInt& lhsValue = lhsInt.getValue();
419*fa0734ecSArgyrios Kyrtzidis 
420*fa0734ecSArgyrios Kyrtzidis         // Swap the left and right sides and flip the operator if doing so
421*fa0734ecSArgyrios Kyrtzidis         // allows us to better reason about the expression (this is a form
422*fa0734ecSArgyrios Kyrtzidis         // of expression canonicalization).
423*fa0734ecSArgyrios Kyrtzidis         // While we're at it, catch some special cases for non-commutative ops.
424*fa0734ecSArgyrios Kyrtzidis         NonLoc tmp = rhs;
425*fa0734ecSArgyrios Kyrtzidis         rhs = lhs;
426*fa0734ecSArgyrios Kyrtzidis         lhs = tmp;
427*fa0734ecSArgyrios Kyrtzidis 
428*fa0734ecSArgyrios Kyrtzidis         switch (op) {
429*fa0734ecSArgyrios Kyrtzidis           case BO_LT:
430*fa0734ecSArgyrios Kyrtzidis           case BO_GT:
431*fa0734ecSArgyrios Kyrtzidis           case BO_LE:
432*fa0734ecSArgyrios Kyrtzidis           case BO_GE:
433*fa0734ecSArgyrios Kyrtzidis             op = ReverseComparison(op);
434*fa0734ecSArgyrios Kyrtzidis             continue;
435*fa0734ecSArgyrios Kyrtzidis           case BO_EQ:
436*fa0734ecSArgyrios Kyrtzidis           case BO_NE:
437*fa0734ecSArgyrios Kyrtzidis           case BO_Add:
438*fa0734ecSArgyrios Kyrtzidis           case BO_Mul:
439*fa0734ecSArgyrios Kyrtzidis           case BO_And:
440*fa0734ecSArgyrios Kyrtzidis           case BO_Xor:
441*fa0734ecSArgyrios Kyrtzidis           case BO_Or:
442*fa0734ecSArgyrios Kyrtzidis             continue;
443*fa0734ecSArgyrios Kyrtzidis           case BO_Shr:
444*fa0734ecSArgyrios Kyrtzidis             if (lhsValue.isAllOnesValue() && lhsValue.isSigned())
445*fa0734ecSArgyrios Kyrtzidis               // At this point lhs and rhs have been swapped.
446*fa0734ecSArgyrios Kyrtzidis               return rhs;
447*fa0734ecSArgyrios Kyrtzidis             // FALL-THROUGH
448*fa0734ecSArgyrios Kyrtzidis           case BO_Shl:
449*fa0734ecSArgyrios Kyrtzidis             if (lhsValue == 0)
450*fa0734ecSArgyrios Kyrtzidis               // At this point lhs and rhs have been swapped.
451*fa0734ecSArgyrios Kyrtzidis               return rhs;
452*fa0734ecSArgyrios Kyrtzidis             return UnknownVal();
453*fa0734ecSArgyrios Kyrtzidis           default:
454*fa0734ecSArgyrios Kyrtzidis             return UnknownVal();
455*fa0734ecSArgyrios Kyrtzidis         }
456*fa0734ecSArgyrios Kyrtzidis       }
457*fa0734ecSArgyrios Kyrtzidis     }
458*fa0734ecSArgyrios Kyrtzidis     case nonloc::SymbolValKind: {
459*fa0734ecSArgyrios Kyrtzidis       nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
460*fa0734ecSArgyrios Kyrtzidis       SymbolRef Sym = slhs->getSymbol();
461*fa0734ecSArgyrios Kyrtzidis       // Does the symbol simplify to a constant?  If so, "fold" the constant
462*fa0734ecSArgyrios Kyrtzidis       // by setting 'lhs' to a ConcreteInt and try again.
463*fa0734ecSArgyrios Kyrtzidis       if (Sym->getType(Context)->isIntegerType())
464*fa0734ecSArgyrios Kyrtzidis         if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
465*fa0734ecSArgyrios Kyrtzidis           // The symbol evaluates to a constant. If necessary, promote the
466*fa0734ecSArgyrios Kyrtzidis           // folded constant (LHS) to the result type.
467*fa0734ecSArgyrios Kyrtzidis           const llvm::APSInt &lhs_I = BasicVals.Convert(resultTy, *Constant);
468*fa0734ecSArgyrios Kyrtzidis           lhs = nonloc::ConcreteInt(lhs_I);
469*fa0734ecSArgyrios Kyrtzidis 
470*fa0734ecSArgyrios Kyrtzidis           // Also promote the RHS (if necessary).
471*fa0734ecSArgyrios Kyrtzidis 
472*fa0734ecSArgyrios Kyrtzidis           // For shifts, it is not necessary to promote the RHS.
473*fa0734ecSArgyrios Kyrtzidis           if (BinaryOperator::isShiftOp(op))
474*fa0734ecSArgyrios Kyrtzidis             continue;
475*fa0734ecSArgyrios Kyrtzidis 
476*fa0734ecSArgyrios Kyrtzidis           // Other operators: do an implicit conversion.  This shouldn't be
477*fa0734ecSArgyrios Kyrtzidis           // necessary once we support truncation/extension of symbolic values.
478*fa0734ecSArgyrios Kyrtzidis           if (nonloc::ConcreteInt *rhs_I = dyn_cast<nonloc::ConcreteInt>(&rhs)){
479*fa0734ecSArgyrios Kyrtzidis             rhs = nonloc::ConcreteInt(BasicVals.Convert(resultTy,
480*fa0734ecSArgyrios Kyrtzidis                                                         rhs_I->getValue()));
481*fa0734ecSArgyrios Kyrtzidis           }
482*fa0734ecSArgyrios Kyrtzidis 
483*fa0734ecSArgyrios Kyrtzidis           continue;
484*fa0734ecSArgyrios Kyrtzidis         }
485*fa0734ecSArgyrios Kyrtzidis 
486*fa0734ecSArgyrios Kyrtzidis       // Is the RHS a symbol we can simplify?
487*fa0734ecSArgyrios Kyrtzidis       if (const nonloc::SymbolVal *srhs = dyn_cast<nonloc::SymbolVal>(&rhs)) {
488*fa0734ecSArgyrios Kyrtzidis         SymbolRef RSym = srhs->getSymbol();
489*fa0734ecSArgyrios Kyrtzidis         if (RSym->getType(Context)->isIntegerType()) {
490*fa0734ecSArgyrios Kyrtzidis           if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
491*fa0734ecSArgyrios Kyrtzidis             // The symbol evaluates to a constant.
492*fa0734ecSArgyrios Kyrtzidis             const llvm::APSInt &rhs_I = BasicVals.Convert(resultTy, *Constant);
493*fa0734ecSArgyrios Kyrtzidis             rhs = nonloc::ConcreteInt(rhs_I);
494*fa0734ecSArgyrios Kyrtzidis           }
495*fa0734ecSArgyrios Kyrtzidis         }
496*fa0734ecSArgyrios Kyrtzidis       }
497*fa0734ecSArgyrios Kyrtzidis 
498*fa0734ecSArgyrios Kyrtzidis       if (isa<nonloc::ConcreteInt>(rhs)) {
499*fa0734ecSArgyrios Kyrtzidis         return MakeSymIntVal(slhs->getSymbol(), op,
500*fa0734ecSArgyrios Kyrtzidis                              cast<nonloc::ConcreteInt>(rhs).getValue(),
501*fa0734ecSArgyrios Kyrtzidis                              resultTy);
502*fa0734ecSArgyrios Kyrtzidis       }
503*fa0734ecSArgyrios Kyrtzidis 
504*fa0734ecSArgyrios Kyrtzidis       return UnknownVal();
505*fa0734ecSArgyrios Kyrtzidis     }
506*fa0734ecSArgyrios Kyrtzidis     }
507*fa0734ecSArgyrios Kyrtzidis   }
508*fa0734ecSArgyrios Kyrtzidis }
509*fa0734ecSArgyrios Kyrtzidis 
510*fa0734ecSArgyrios Kyrtzidis // FIXME: all this logic will change if/when we have MemRegion::getLocation().
511*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalBinOpLL(const GRState *state,
512*fa0734ecSArgyrios Kyrtzidis                                   BinaryOperator::Opcode op,
513*fa0734ecSArgyrios Kyrtzidis                                   Loc lhs, Loc rhs,
514*fa0734ecSArgyrios Kyrtzidis                                   QualType resultTy) {
515*fa0734ecSArgyrios Kyrtzidis   // Only comparisons and subtractions are valid operations on two pointers.
516*fa0734ecSArgyrios Kyrtzidis   // See [C99 6.5.5 through 6.5.14] or [C++0x 5.6 through 5.15].
517*fa0734ecSArgyrios Kyrtzidis   // However, if a pointer is casted to an integer, evalBinOpNN may end up
518*fa0734ecSArgyrios Kyrtzidis   // calling this function with another operation (PR7527). We don't attempt to
519*fa0734ecSArgyrios Kyrtzidis   // model this for now, but it could be useful, particularly when the
520*fa0734ecSArgyrios Kyrtzidis   // "location" is actually an integer value that's been passed through a void*.
521*fa0734ecSArgyrios Kyrtzidis   if (!(BinaryOperator::isComparisonOp(op) || op == BO_Sub))
522*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
523*fa0734ecSArgyrios Kyrtzidis 
524*fa0734ecSArgyrios Kyrtzidis   // Special cases for when both sides are identical.
525*fa0734ecSArgyrios Kyrtzidis   if (lhs == rhs) {
526*fa0734ecSArgyrios Kyrtzidis     switch (op) {
527*fa0734ecSArgyrios Kyrtzidis     default:
528*fa0734ecSArgyrios Kyrtzidis       assert(false && "Unimplemented operation for two identical values");
529*fa0734ecSArgyrios Kyrtzidis       return UnknownVal();
530*fa0734ecSArgyrios Kyrtzidis     case BO_Sub:
531*fa0734ecSArgyrios Kyrtzidis       return makeZeroVal(resultTy);
532*fa0734ecSArgyrios Kyrtzidis     case BO_EQ:
533*fa0734ecSArgyrios Kyrtzidis     case BO_LE:
534*fa0734ecSArgyrios Kyrtzidis     case BO_GE:
535*fa0734ecSArgyrios Kyrtzidis       return makeTruthVal(true, resultTy);
536*fa0734ecSArgyrios Kyrtzidis     case BO_NE:
537*fa0734ecSArgyrios Kyrtzidis     case BO_LT:
538*fa0734ecSArgyrios Kyrtzidis     case BO_GT:
539*fa0734ecSArgyrios Kyrtzidis       return makeTruthVal(false, resultTy);
540*fa0734ecSArgyrios Kyrtzidis     }
541*fa0734ecSArgyrios Kyrtzidis   }
542*fa0734ecSArgyrios Kyrtzidis 
543*fa0734ecSArgyrios Kyrtzidis   switch (lhs.getSubKind()) {
544*fa0734ecSArgyrios Kyrtzidis   default:
545*fa0734ecSArgyrios Kyrtzidis     assert(false && "Ordering not implemented for this Loc.");
546*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
547*fa0734ecSArgyrios Kyrtzidis 
548*fa0734ecSArgyrios Kyrtzidis   case loc::GotoLabelKind:
549*fa0734ecSArgyrios Kyrtzidis     // The only thing we know about labels is that they're non-null.
550*fa0734ecSArgyrios Kyrtzidis     if (rhs.isZeroConstant()) {
551*fa0734ecSArgyrios Kyrtzidis       switch (op) {
552*fa0734ecSArgyrios Kyrtzidis       default:
553*fa0734ecSArgyrios Kyrtzidis         break;
554*fa0734ecSArgyrios Kyrtzidis       case BO_Sub:
555*fa0734ecSArgyrios Kyrtzidis         return evalCastL(lhs, resultTy);
556*fa0734ecSArgyrios Kyrtzidis       case BO_EQ:
557*fa0734ecSArgyrios Kyrtzidis       case BO_LE:
558*fa0734ecSArgyrios Kyrtzidis       case BO_LT:
559*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(false, resultTy);
560*fa0734ecSArgyrios Kyrtzidis       case BO_NE:
561*fa0734ecSArgyrios Kyrtzidis       case BO_GT:
562*fa0734ecSArgyrios Kyrtzidis       case BO_GE:
563*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(true, resultTy);
564*fa0734ecSArgyrios Kyrtzidis       }
565*fa0734ecSArgyrios Kyrtzidis     }
566*fa0734ecSArgyrios Kyrtzidis     // There may be two labels for the same location, and a function region may
567*fa0734ecSArgyrios Kyrtzidis     // have the same address as a label at the start of the function (depending
568*fa0734ecSArgyrios Kyrtzidis     // on the ABI).
569*fa0734ecSArgyrios Kyrtzidis     // FIXME: we can probably do a comparison against other MemRegions, though.
570*fa0734ecSArgyrios Kyrtzidis     // FIXME: is there a way to tell if two labels refer to the same location?
571*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
572*fa0734ecSArgyrios Kyrtzidis 
573*fa0734ecSArgyrios Kyrtzidis   case loc::ConcreteIntKind: {
574*fa0734ecSArgyrios Kyrtzidis     // If one of the operands is a symbol and the other is a constant,
575*fa0734ecSArgyrios Kyrtzidis     // build an expression for use by the constraint manager.
576*fa0734ecSArgyrios Kyrtzidis     if (SymbolRef rSym = rhs.getAsLocSymbol()) {
577*fa0734ecSArgyrios Kyrtzidis       // We can only build expressions with symbols on the left,
578*fa0734ecSArgyrios Kyrtzidis       // so we need a reversible operator.
579*fa0734ecSArgyrios Kyrtzidis       if (!BinaryOperator::isComparisonOp(op))
580*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
581*fa0734ecSArgyrios Kyrtzidis 
582*fa0734ecSArgyrios Kyrtzidis       const llvm::APSInt &lVal = cast<loc::ConcreteInt>(lhs).getValue();
583*fa0734ecSArgyrios Kyrtzidis       return makeNonLoc(rSym, ReverseComparison(op), lVal, resultTy);
584*fa0734ecSArgyrios Kyrtzidis     }
585*fa0734ecSArgyrios Kyrtzidis 
586*fa0734ecSArgyrios Kyrtzidis     // If both operands are constants, just perform the operation.
587*fa0734ecSArgyrios Kyrtzidis     if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
588*fa0734ecSArgyrios Kyrtzidis       SVal ResultVal = cast<loc::ConcreteInt>(lhs).evalBinOp(BasicVals, op,
589*fa0734ecSArgyrios Kyrtzidis                                                              *rInt);
590*fa0734ecSArgyrios Kyrtzidis       if (Loc *Result = dyn_cast<Loc>(&ResultVal))
591*fa0734ecSArgyrios Kyrtzidis         return evalCastL(*Result, resultTy);
592*fa0734ecSArgyrios Kyrtzidis       else
593*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
594*fa0734ecSArgyrios Kyrtzidis     }
595*fa0734ecSArgyrios Kyrtzidis 
596*fa0734ecSArgyrios Kyrtzidis     // Special case comparisons against NULL.
597*fa0734ecSArgyrios Kyrtzidis     // This must come after the test if the RHS is a symbol, which is used to
598*fa0734ecSArgyrios Kyrtzidis     // build constraints. The address of any non-symbolic region is guaranteed
599*fa0734ecSArgyrios Kyrtzidis     // to be non-NULL, as is any label.
600*fa0734ecSArgyrios Kyrtzidis     assert(isa<loc::MemRegionVal>(rhs) || isa<loc::GotoLabel>(rhs));
601*fa0734ecSArgyrios Kyrtzidis     if (lhs.isZeroConstant()) {
602*fa0734ecSArgyrios Kyrtzidis       switch (op) {
603*fa0734ecSArgyrios Kyrtzidis       default:
604*fa0734ecSArgyrios Kyrtzidis         break;
605*fa0734ecSArgyrios Kyrtzidis       case BO_EQ:
606*fa0734ecSArgyrios Kyrtzidis       case BO_GT:
607*fa0734ecSArgyrios Kyrtzidis       case BO_GE:
608*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(false, resultTy);
609*fa0734ecSArgyrios Kyrtzidis       case BO_NE:
610*fa0734ecSArgyrios Kyrtzidis       case BO_LT:
611*fa0734ecSArgyrios Kyrtzidis       case BO_LE:
612*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(true, resultTy);
613*fa0734ecSArgyrios Kyrtzidis       }
614*fa0734ecSArgyrios Kyrtzidis     }
615*fa0734ecSArgyrios Kyrtzidis 
616*fa0734ecSArgyrios Kyrtzidis     // Comparing an arbitrary integer to a region or label address is
617*fa0734ecSArgyrios Kyrtzidis     // completely unknowable.
618*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
619*fa0734ecSArgyrios Kyrtzidis   }
620*fa0734ecSArgyrios Kyrtzidis   case loc::MemRegionKind: {
621*fa0734ecSArgyrios Kyrtzidis     if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
622*fa0734ecSArgyrios Kyrtzidis       // If one of the operands is a symbol and the other is a constant,
623*fa0734ecSArgyrios Kyrtzidis       // build an expression for use by the constraint manager.
624*fa0734ecSArgyrios Kyrtzidis       if (SymbolRef lSym = lhs.getAsLocSymbol())
625*fa0734ecSArgyrios Kyrtzidis         return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
626*fa0734ecSArgyrios Kyrtzidis 
627*fa0734ecSArgyrios Kyrtzidis       // Special case comparisons to NULL.
628*fa0734ecSArgyrios Kyrtzidis       // This must come after the test if the LHS is a symbol, which is used to
629*fa0734ecSArgyrios Kyrtzidis       // build constraints. The address of any non-symbolic region is guaranteed
630*fa0734ecSArgyrios Kyrtzidis       // to be non-NULL.
631*fa0734ecSArgyrios Kyrtzidis       if (rInt->isZeroConstant()) {
632*fa0734ecSArgyrios Kyrtzidis         switch (op) {
633*fa0734ecSArgyrios Kyrtzidis         default:
634*fa0734ecSArgyrios Kyrtzidis           break;
635*fa0734ecSArgyrios Kyrtzidis         case BO_Sub:
636*fa0734ecSArgyrios Kyrtzidis           return evalCastL(lhs, resultTy);
637*fa0734ecSArgyrios Kyrtzidis         case BO_EQ:
638*fa0734ecSArgyrios Kyrtzidis         case BO_LT:
639*fa0734ecSArgyrios Kyrtzidis         case BO_LE:
640*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(false, resultTy);
641*fa0734ecSArgyrios Kyrtzidis         case BO_NE:
642*fa0734ecSArgyrios Kyrtzidis         case BO_GT:
643*fa0734ecSArgyrios Kyrtzidis         case BO_GE:
644*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(true, resultTy);
645*fa0734ecSArgyrios Kyrtzidis         }
646*fa0734ecSArgyrios Kyrtzidis       }
647*fa0734ecSArgyrios Kyrtzidis 
648*fa0734ecSArgyrios Kyrtzidis       // Comparing a region to an arbitrary integer is completely unknowable.
649*fa0734ecSArgyrios Kyrtzidis       return UnknownVal();
650*fa0734ecSArgyrios Kyrtzidis     }
651*fa0734ecSArgyrios Kyrtzidis 
652*fa0734ecSArgyrios Kyrtzidis     // Get both values as regions, if possible.
653*fa0734ecSArgyrios Kyrtzidis     const MemRegion *LeftMR = lhs.getAsRegion();
654*fa0734ecSArgyrios Kyrtzidis     assert(LeftMR && "MemRegionKind SVal doesn't have a region!");
655*fa0734ecSArgyrios Kyrtzidis 
656*fa0734ecSArgyrios Kyrtzidis     const MemRegion *RightMR = rhs.getAsRegion();
657*fa0734ecSArgyrios Kyrtzidis     if (!RightMR)
658*fa0734ecSArgyrios Kyrtzidis       // The RHS is probably a label, which in theory could address a region.
659*fa0734ecSArgyrios Kyrtzidis       // FIXME: we can probably make a more useful statement about non-code
660*fa0734ecSArgyrios Kyrtzidis       // regions, though.
661*fa0734ecSArgyrios Kyrtzidis       return UnknownVal();
662*fa0734ecSArgyrios Kyrtzidis 
663*fa0734ecSArgyrios Kyrtzidis     // If both values wrap regions, see if they're from different base regions.
664*fa0734ecSArgyrios Kyrtzidis     const MemRegion *LeftBase = LeftMR->getBaseRegion();
665*fa0734ecSArgyrios Kyrtzidis     const MemRegion *RightBase = RightMR->getBaseRegion();
666*fa0734ecSArgyrios Kyrtzidis     if (LeftBase != RightBase &&
667*fa0734ecSArgyrios Kyrtzidis         !isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) {
668*fa0734ecSArgyrios Kyrtzidis       switch (op) {
669*fa0734ecSArgyrios Kyrtzidis       default:
670*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
671*fa0734ecSArgyrios Kyrtzidis       case BO_EQ:
672*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(false, resultTy);
673*fa0734ecSArgyrios Kyrtzidis       case BO_NE:
674*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(true, resultTy);
675*fa0734ecSArgyrios Kyrtzidis       }
676*fa0734ecSArgyrios Kyrtzidis     }
677*fa0734ecSArgyrios Kyrtzidis 
678*fa0734ecSArgyrios Kyrtzidis     // The two regions are from the same base region. See if they're both a
679*fa0734ecSArgyrios Kyrtzidis     // type of region we know how to compare.
680*fa0734ecSArgyrios Kyrtzidis 
681*fa0734ecSArgyrios Kyrtzidis     // FIXME: If/when there is a getAsRawOffset() for FieldRegions, this
682*fa0734ecSArgyrios Kyrtzidis     // ElementRegion path and the FieldRegion path below should be unified.
683*fa0734ecSArgyrios Kyrtzidis     if (const ElementRegion *LeftER = dyn_cast<ElementRegion>(LeftMR)) {
684*fa0734ecSArgyrios Kyrtzidis       // First see if the right region is also an ElementRegion.
685*fa0734ecSArgyrios Kyrtzidis       const ElementRegion *RightER = dyn_cast<ElementRegion>(RightMR);
686*fa0734ecSArgyrios Kyrtzidis       if (!RightER)
687*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
688*fa0734ecSArgyrios Kyrtzidis 
689*fa0734ecSArgyrios Kyrtzidis       // Next, see if the two ERs have the same super-region and matching types.
690*fa0734ecSArgyrios Kyrtzidis       // FIXME: This should do something useful even if the types don't match,
691*fa0734ecSArgyrios Kyrtzidis       // though if both indexes are constant the RegionRawOffset path will
692*fa0734ecSArgyrios Kyrtzidis       // give the correct answer.
693*fa0734ecSArgyrios Kyrtzidis       if (LeftER->getSuperRegion() == RightER->getSuperRegion() &&
694*fa0734ecSArgyrios Kyrtzidis           LeftER->getElementType() == RightER->getElementType()) {
695*fa0734ecSArgyrios Kyrtzidis         // Get the left index and cast it to the correct type.
696*fa0734ecSArgyrios Kyrtzidis         // If the index is unknown or undefined, bail out here.
697*fa0734ecSArgyrios Kyrtzidis         SVal LeftIndexVal = LeftER->getIndex();
698*fa0734ecSArgyrios Kyrtzidis         NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
699*fa0734ecSArgyrios Kyrtzidis         if (!LeftIndex)
700*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
701*fa0734ecSArgyrios Kyrtzidis         LeftIndexVal = evalCastNL(*LeftIndex, resultTy);
702*fa0734ecSArgyrios Kyrtzidis         LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
703*fa0734ecSArgyrios Kyrtzidis         if (!LeftIndex)
704*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
705*fa0734ecSArgyrios Kyrtzidis 
706*fa0734ecSArgyrios Kyrtzidis         // Do the same for the right index.
707*fa0734ecSArgyrios Kyrtzidis         SVal RightIndexVal = RightER->getIndex();
708*fa0734ecSArgyrios Kyrtzidis         NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
709*fa0734ecSArgyrios Kyrtzidis         if (!RightIndex)
710*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
711*fa0734ecSArgyrios Kyrtzidis         RightIndexVal = evalCastNL(*RightIndex, resultTy);
712*fa0734ecSArgyrios Kyrtzidis         RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
713*fa0734ecSArgyrios Kyrtzidis         if (!RightIndex)
714*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
715*fa0734ecSArgyrios Kyrtzidis 
716*fa0734ecSArgyrios Kyrtzidis         // Actually perform the operation.
717*fa0734ecSArgyrios Kyrtzidis         // evalBinOpNN expects the two indexes to already be the right type.
718*fa0734ecSArgyrios Kyrtzidis         return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
719*fa0734ecSArgyrios Kyrtzidis       }
720*fa0734ecSArgyrios Kyrtzidis 
721*fa0734ecSArgyrios Kyrtzidis       // If the element indexes aren't comparable, see if the raw offsets are.
722*fa0734ecSArgyrios Kyrtzidis       RegionRawOffset LeftOffset = LeftER->getAsArrayOffset();
723*fa0734ecSArgyrios Kyrtzidis       RegionRawOffset RightOffset = RightER->getAsArrayOffset();
724*fa0734ecSArgyrios Kyrtzidis 
725*fa0734ecSArgyrios Kyrtzidis       if (LeftOffset.getRegion() != NULL &&
726*fa0734ecSArgyrios Kyrtzidis           LeftOffset.getRegion() == RightOffset.getRegion()) {
727*fa0734ecSArgyrios Kyrtzidis         CharUnits left = LeftOffset.getOffset();
728*fa0734ecSArgyrios Kyrtzidis         CharUnits right = RightOffset.getOffset();
729*fa0734ecSArgyrios Kyrtzidis 
730*fa0734ecSArgyrios Kyrtzidis         switch (op) {
731*fa0734ecSArgyrios Kyrtzidis         default:
732*fa0734ecSArgyrios Kyrtzidis           return UnknownVal();
733*fa0734ecSArgyrios Kyrtzidis         case BO_LT:
734*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(left < right, resultTy);
735*fa0734ecSArgyrios Kyrtzidis         case BO_GT:
736*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(left > right, resultTy);
737*fa0734ecSArgyrios Kyrtzidis         case BO_LE:
738*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(left <= right, resultTy);
739*fa0734ecSArgyrios Kyrtzidis         case BO_GE:
740*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(left >= right, resultTy);
741*fa0734ecSArgyrios Kyrtzidis         case BO_EQ:
742*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(left == right, resultTy);
743*fa0734ecSArgyrios Kyrtzidis         case BO_NE:
744*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(left != right, resultTy);
745*fa0734ecSArgyrios Kyrtzidis         }
746*fa0734ecSArgyrios Kyrtzidis       }
747*fa0734ecSArgyrios Kyrtzidis 
748*fa0734ecSArgyrios Kyrtzidis       // If we get here, we have no way of comparing the ElementRegions.
749*fa0734ecSArgyrios Kyrtzidis       return UnknownVal();
750*fa0734ecSArgyrios Kyrtzidis     }
751*fa0734ecSArgyrios Kyrtzidis 
752*fa0734ecSArgyrios Kyrtzidis     // See if both regions are fields of the same structure.
753*fa0734ecSArgyrios Kyrtzidis     // FIXME: This doesn't handle nesting, inheritance, or Objective-C ivars.
754*fa0734ecSArgyrios Kyrtzidis     if (const FieldRegion *LeftFR = dyn_cast<FieldRegion>(LeftMR)) {
755*fa0734ecSArgyrios Kyrtzidis       // Only comparisons are meaningful here!
756*fa0734ecSArgyrios Kyrtzidis       if (!BinaryOperator::isComparisonOp(op))
757*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
758*fa0734ecSArgyrios Kyrtzidis 
759*fa0734ecSArgyrios Kyrtzidis       // First see if the right region is also a FieldRegion.
760*fa0734ecSArgyrios Kyrtzidis       const FieldRegion *RightFR = dyn_cast<FieldRegion>(RightMR);
761*fa0734ecSArgyrios Kyrtzidis       if (!RightFR)
762*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
763*fa0734ecSArgyrios Kyrtzidis 
764*fa0734ecSArgyrios Kyrtzidis       // Next, see if the two FRs have the same super-region.
765*fa0734ecSArgyrios Kyrtzidis       // FIXME: This doesn't handle casts yet, and simply stripping the casts
766*fa0734ecSArgyrios Kyrtzidis       // doesn't help.
767*fa0734ecSArgyrios Kyrtzidis       if (LeftFR->getSuperRegion() != RightFR->getSuperRegion())
768*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
769*fa0734ecSArgyrios Kyrtzidis 
770*fa0734ecSArgyrios Kyrtzidis       const FieldDecl *LeftFD = LeftFR->getDecl();
771*fa0734ecSArgyrios Kyrtzidis       const FieldDecl *RightFD = RightFR->getDecl();
772*fa0734ecSArgyrios Kyrtzidis       const RecordDecl *RD = LeftFD->getParent();
773*fa0734ecSArgyrios Kyrtzidis 
774*fa0734ecSArgyrios Kyrtzidis       // Make sure the two FRs are from the same kind of record. Just in case!
775*fa0734ecSArgyrios Kyrtzidis       // FIXME: This is probably where inheritance would be a problem.
776*fa0734ecSArgyrios Kyrtzidis       if (RD != RightFD->getParent())
777*fa0734ecSArgyrios Kyrtzidis         return UnknownVal();
778*fa0734ecSArgyrios Kyrtzidis 
779*fa0734ecSArgyrios Kyrtzidis       // We know for sure that the two fields are not the same, since that
780*fa0734ecSArgyrios Kyrtzidis       // would have given us the same SVal.
781*fa0734ecSArgyrios Kyrtzidis       if (op == BO_EQ)
782*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(false, resultTy);
783*fa0734ecSArgyrios Kyrtzidis       if (op == BO_NE)
784*fa0734ecSArgyrios Kyrtzidis         return makeTruthVal(true, resultTy);
785*fa0734ecSArgyrios Kyrtzidis 
786*fa0734ecSArgyrios Kyrtzidis       // Iterate through the fields and see which one comes first.
787*fa0734ecSArgyrios Kyrtzidis       // [C99 6.7.2.1.13] "Within a structure object, the non-bit-field
788*fa0734ecSArgyrios Kyrtzidis       // members and the units in which bit-fields reside have addresses that
789*fa0734ecSArgyrios Kyrtzidis       // increase in the order in which they are declared."
790*fa0734ecSArgyrios Kyrtzidis       bool leftFirst = (op == BO_LT || op == BO_LE);
791*fa0734ecSArgyrios Kyrtzidis       for (RecordDecl::field_iterator I = RD->field_begin(),
792*fa0734ecSArgyrios Kyrtzidis            E = RD->field_end(); I!=E; ++I) {
793*fa0734ecSArgyrios Kyrtzidis         if (*I == LeftFD)
794*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(leftFirst, resultTy);
795*fa0734ecSArgyrios Kyrtzidis         if (*I == RightFD)
796*fa0734ecSArgyrios Kyrtzidis           return makeTruthVal(!leftFirst, resultTy);
797*fa0734ecSArgyrios Kyrtzidis       }
798*fa0734ecSArgyrios Kyrtzidis 
799*fa0734ecSArgyrios Kyrtzidis       assert(false && "Fields not found in parent record's definition");
800*fa0734ecSArgyrios Kyrtzidis     }
801*fa0734ecSArgyrios Kyrtzidis 
802*fa0734ecSArgyrios Kyrtzidis     // If we get here, we have no way of comparing the regions.
803*fa0734ecSArgyrios Kyrtzidis     return UnknownVal();
804*fa0734ecSArgyrios Kyrtzidis   }
805*fa0734ecSArgyrios Kyrtzidis   }
806*fa0734ecSArgyrios Kyrtzidis }
807*fa0734ecSArgyrios Kyrtzidis 
808*fa0734ecSArgyrios Kyrtzidis SVal SimpleSValBuilder::evalBinOpLN(const GRState *state,
809*fa0734ecSArgyrios Kyrtzidis                                   BinaryOperator::Opcode op,
810*fa0734ecSArgyrios Kyrtzidis                                   Loc lhs, NonLoc rhs, QualType resultTy) {
811*fa0734ecSArgyrios Kyrtzidis 
812*fa0734ecSArgyrios Kyrtzidis   // Special case: rhs is a zero constant.
813*fa0734ecSArgyrios Kyrtzidis   if (rhs.isZeroConstant())
814*fa0734ecSArgyrios Kyrtzidis     return lhs;
815*fa0734ecSArgyrios Kyrtzidis 
816*fa0734ecSArgyrios Kyrtzidis   // Special case: 'rhs' is an integer that has the same width as a pointer and
817*fa0734ecSArgyrios Kyrtzidis   // we are using the integer location in a comparison.  Normally this cannot be
818*fa0734ecSArgyrios Kyrtzidis   // triggered, but transfer functions like those for OSCommpareAndSwapBarrier32
819*fa0734ecSArgyrios Kyrtzidis   // can generate comparisons that trigger this code.
820*fa0734ecSArgyrios Kyrtzidis   // FIXME: Are all locations guaranteed to have pointer width?
821*fa0734ecSArgyrios Kyrtzidis   if (BinaryOperator::isComparisonOp(op)) {
822*fa0734ecSArgyrios Kyrtzidis     if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
823*fa0734ecSArgyrios Kyrtzidis       const llvm::APSInt *x = &rhsInt->getValue();
824*fa0734ecSArgyrios Kyrtzidis       ASTContext &ctx = Context;
825*fa0734ecSArgyrios Kyrtzidis       if (ctx.getTypeSize(ctx.VoidPtrTy) == x->getBitWidth()) {
826*fa0734ecSArgyrios Kyrtzidis         // Convert the signedness of the integer (if necessary).
827*fa0734ecSArgyrios Kyrtzidis         if (x->isSigned())
828*fa0734ecSArgyrios Kyrtzidis           x = &getBasicValueFactory().getValue(*x, true);
829*fa0734ecSArgyrios Kyrtzidis 
830*fa0734ecSArgyrios Kyrtzidis         return evalBinOpLL(state, op, lhs, loc::ConcreteInt(*x), resultTy);
831*fa0734ecSArgyrios Kyrtzidis       }
832*fa0734ecSArgyrios Kyrtzidis     }
833*fa0734ecSArgyrios Kyrtzidis   }
834*fa0734ecSArgyrios Kyrtzidis 
835*fa0734ecSArgyrios Kyrtzidis   // We are dealing with pointer arithmetic.
836*fa0734ecSArgyrios Kyrtzidis 
837*fa0734ecSArgyrios Kyrtzidis   // Handle pointer arithmetic on constant values.
838*fa0734ecSArgyrios Kyrtzidis   if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
839*fa0734ecSArgyrios Kyrtzidis     if (loc::ConcreteInt *lhsInt = dyn_cast<loc::ConcreteInt>(&lhs)) {
840*fa0734ecSArgyrios Kyrtzidis       const llvm::APSInt &leftI = lhsInt->getValue();
841*fa0734ecSArgyrios Kyrtzidis       assert(leftI.isUnsigned());
842*fa0734ecSArgyrios Kyrtzidis       llvm::APSInt rightI(rhsInt->getValue(), /* isUnsigned */ true);
843*fa0734ecSArgyrios Kyrtzidis 
844*fa0734ecSArgyrios Kyrtzidis       // Convert the bitwidth of rightI.  This should deal with overflow
845*fa0734ecSArgyrios Kyrtzidis       // since we are dealing with concrete values.
846*fa0734ecSArgyrios Kyrtzidis       rightI = rightI.extOrTrunc(leftI.getBitWidth());
847*fa0734ecSArgyrios Kyrtzidis 
848*fa0734ecSArgyrios Kyrtzidis       // Offset the increment by the pointer size.
849*fa0734ecSArgyrios Kyrtzidis       llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true);
850*fa0734ecSArgyrios Kyrtzidis       rightI *= Multiplicand;
851*fa0734ecSArgyrios Kyrtzidis 
852*fa0734ecSArgyrios Kyrtzidis       // Compute the adjusted pointer.
853*fa0734ecSArgyrios Kyrtzidis       switch (op) {
854*fa0734ecSArgyrios Kyrtzidis         case BO_Add:
855*fa0734ecSArgyrios Kyrtzidis           rightI = leftI + rightI;
856*fa0734ecSArgyrios Kyrtzidis           break;
857*fa0734ecSArgyrios Kyrtzidis         case BO_Sub:
858*fa0734ecSArgyrios Kyrtzidis           rightI = leftI - rightI;
859*fa0734ecSArgyrios Kyrtzidis           break;
860*fa0734ecSArgyrios Kyrtzidis         default:
861*fa0734ecSArgyrios Kyrtzidis           llvm_unreachable("Invalid pointer arithmetic operation");
862*fa0734ecSArgyrios Kyrtzidis       }
863*fa0734ecSArgyrios Kyrtzidis       return loc::ConcreteInt(getBasicValueFactory().getValue(rightI));
864*fa0734ecSArgyrios Kyrtzidis     }
865*fa0734ecSArgyrios Kyrtzidis   }
866*fa0734ecSArgyrios Kyrtzidis 
867*fa0734ecSArgyrios Kyrtzidis   // Handle cases where 'lhs' is a region.
868*fa0734ecSArgyrios Kyrtzidis   if (const MemRegion *region = lhs.getAsRegion()) {
869*fa0734ecSArgyrios Kyrtzidis     rhs = cast<NonLoc>(convertToArrayIndex(rhs));
870*fa0734ecSArgyrios Kyrtzidis     SVal index = UnknownVal();
871*fa0734ecSArgyrios Kyrtzidis     const MemRegion *superR = 0;
872*fa0734ecSArgyrios Kyrtzidis     QualType elementType;
873*fa0734ecSArgyrios Kyrtzidis 
874*fa0734ecSArgyrios Kyrtzidis     if (const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
875*fa0734ecSArgyrios Kyrtzidis       index = evalBinOpNN(state, BO_Add, elemReg->getIndex(), rhs,
876*fa0734ecSArgyrios Kyrtzidis                           getArrayIndexType());
877*fa0734ecSArgyrios Kyrtzidis       superR = elemReg->getSuperRegion();
878*fa0734ecSArgyrios Kyrtzidis       elementType = elemReg->getElementType();
879*fa0734ecSArgyrios Kyrtzidis     }
880*fa0734ecSArgyrios Kyrtzidis     else if (isa<SubRegion>(region)) {
881*fa0734ecSArgyrios Kyrtzidis       superR = region;
882*fa0734ecSArgyrios Kyrtzidis       index = rhs;
883*fa0734ecSArgyrios Kyrtzidis       if (const PointerType *PT = resultTy->getAs<PointerType>()) {
884*fa0734ecSArgyrios Kyrtzidis         elementType = PT->getPointeeType();
885*fa0734ecSArgyrios Kyrtzidis       }
886*fa0734ecSArgyrios Kyrtzidis       else {
887*fa0734ecSArgyrios Kyrtzidis         const ObjCObjectPointerType *OT =
888*fa0734ecSArgyrios Kyrtzidis           resultTy->getAs<ObjCObjectPointerType>();
889*fa0734ecSArgyrios Kyrtzidis         elementType = OT->getPointeeType();
890*fa0734ecSArgyrios Kyrtzidis       }
891*fa0734ecSArgyrios Kyrtzidis     }
892*fa0734ecSArgyrios Kyrtzidis 
893*fa0734ecSArgyrios Kyrtzidis     if (NonLoc *indexV = dyn_cast<NonLoc>(&index)) {
894*fa0734ecSArgyrios Kyrtzidis       return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV,
895*fa0734ecSArgyrios Kyrtzidis                                                        superR, getContext()));
896*fa0734ecSArgyrios Kyrtzidis     }
897*fa0734ecSArgyrios Kyrtzidis   }
898*fa0734ecSArgyrios Kyrtzidis   return UnknownVal();
899*fa0734ecSArgyrios Kyrtzidis }
900*fa0734ecSArgyrios Kyrtzidis 
901*fa0734ecSArgyrios Kyrtzidis const llvm::APSInt *SimpleSValBuilder::getKnownValue(const GRState *state,
902*fa0734ecSArgyrios Kyrtzidis                                                    SVal V) {
903*fa0734ecSArgyrios Kyrtzidis   if (V.isUnknownOrUndef())
904*fa0734ecSArgyrios Kyrtzidis     return NULL;
905*fa0734ecSArgyrios Kyrtzidis 
906*fa0734ecSArgyrios Kyrtzidis   if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
907*fa0734ecSArgyrios Kyrtzidis     return &X->getValue();
908*fa0734ecSArgyrios Kyrtzidis 
909*fa0734ecSArgyrios Kyrtzidis   if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
910*fa0734ecSArgyrios Kyrtzidis     return &X->getValue();
911*fa0734ecSArgyrios Kyrtzidis 
912*fa0734ecSArgyrios Kyrtzidis   if (SymbolRef Sym = V.getAsSymbol())
913*fa0734ecSArgyrios Kyrtzidis     return state->getSymVal(Sym);
914*fa0734ecSArgyrios Kyrtzidis 
915*fa0734ecSArgyrios Kyrtzidis   // FIXME: Add support for SymExprs.
916*fa0734ecSArgyrios Kyrtzidis   return NULL;
917*fa0734ecSArgyrios Kyrtzidis }
918