1 // SValBuilder.cpp - Basic class for all SValBuilder implementations -*- 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 SValBuilder, the base class for all (complete) SValBuilder
11 //  implementations.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
17 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
20 
21 using namespace clang;
22 using namespace ento;
23 
24 //===----------------------------------------------------------------------===//
25 // Basic SVal creation.
26 //===----------------------------------------------------------------------===//
27 
28 DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {
29   if (Loc::isLocType(type))
30     return makeNull();
31 
32   if (type->isIntegerType())
33     return makeIntVal(0, type);
34 
35   // FIXME: Handle floats.
36   // FIXME: Handle structs.
37   return UnknownVal();
38 }
39 
40 
41 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
42                                 const llvm::APSInt& rhs, QualType type) {
43   // The Environment ensures we always get a persistent APSInt in
44   // BasicValueFactory, so we don't need to get the APSInt from
45   // BasicValueFactory again.
46   assert(lhs);
47   assert(!Loc::isLocType(type));
48   return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
49 }
50 
51 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
52                                const SymExpr *rhs, QualType type) {
53   assert(lhs && rhs);
54   assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
55   assert(!Loc::isLocType(type));
56   return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
57 }
58 
59 NonLoc SValBuilder::makeNonLoc(const SymExpr *operand,
60                                QualType fromTy, QualType toTy) {
61   assert(operand);
62   assert(!Loc::isLocType(toTy));
63   return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy));
64 }
65 
66 SVal SValBuilder::convertToArrayIndex(SVal val) {
67   if (val.isUnknownOrUndef())
68     return val;
69 
70   // Common case: we have an appropriately sized integer.
71   if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&val)) {
72     const llvm::APSInt& I = CI->getValue();
73     if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
74       return val;
75   }
76 
77   return evalCastFromNonLoc(cast<NonLoc>(val), ArrayIndexTy);
78 }
79 
80 DefinedOrUnknownSVal
81 SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
82   QualType T = region->getValueType();
83 
84   if (!SymbolManager::canSymbolicate(T))
85     return UnknownVal();
86 
87   SymbolRef sym = SymMgr.getRegionValueSymbol(region);
88 
89   if (Loc::isLocType(T))
90     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
91 
92   return nonloc::SymbolVal(sym);
93 }
94 
95 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag,
96                                                        const Expr *expr,
97                                                        unsigned count) {
98   QualType T = expr->getType();
99   return getConjuredSymbolVal(symbolTag, expr, T, count);
100 }
101 
102 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag,
103                                                        const Expr *expr,
104                                                        QualType type,
105                                                        unsigned count) {
106   if (!SymbolManager::canSymbolicate(type))
107     return UnknownVal();
108 
109   SymbolRef sym = SymMgr.getConjuredSymbol(expr, type, count, symbolTag);
110 
111   if (Loc::isLocType(type))
112     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
113 
114   return nonloc::SymbolVal(sym);
115 }
116 
117 DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
118                                               const MemRegion *region,
119                                               const Expr *expr, QualType type,
120                                               unsigned count) {
121   assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type");
122 
123   SymbolRef sym =
124       SymMgr.getMetadataSymbol(region, expr, type, count, symbolTag);
125 
126   if (Loc::isLocType(type))
127     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
128 
129   return nonloc::SymbolVal(sym);
130 }
131 
132 DefinedOrUnknownSVal
133 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
134                                              const TypedValueRegion *region) {
135   QualType T = region->getValueType();
136 
137   if (!SymbolManager::canSymbolicate(T))
138     return UnknownVal();
139 
140   SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region);
141 
142   if (Loc::isLocType(T))
143     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
144 
145   return nonloc::SymbolVal(sym);
146 }
147 
148 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) {
149   return loc::MemRegionVal(MemMgr.getFunctionTextRegion(func));
150 }
151 
152 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
153                                          CanQualType locTy,
154                                          const LocationContext *locContext) {
155   const BlockTextRegion *BC =
156     MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext());
157   const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext);
158   return loc::MemRegionVal(BD);
159 }
160 
161 //===----------------------------------------------------------------------===//
162 
163 SVal SValBuilder::generateUnknownVal(const ProgramState *State,
164                                      BinaryOperator::Opcode Op,
165                                      NonLoc LHS, NonLoc RHS,
166                                      QualType ResultTy) {
167   // If operands are tainted, create a symbol to ensure that we propagate taint.
168   if (State->isTainted(RHS) || State->isTainted(LHS)) {
169     const SymExpr *symLHS;
170     const SymExpr *symRHS;
171 
172     if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) {
173       symLHS = LHS.getAsSymExpr();
174       return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
175     }
176 
177     symLHS = LHS.getAsSymExpr();
178     symRHS = RHS.getAsSymExpr();
179     return makeNonLoc(symLHS, Op, symRHS, ResultTy);
180   }
181   return UnknownVal();
182 }
183 
184 
185 SVal SValBuilder::evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
186                             SVal lhs, SVal rhs, QualType type) {
187 
188   if (lhs.isUndef() || rhs.isUndef())
189     return UndefinedVal();
190 
191   if (lhs.isUnknown() || rhs.isUnknown())
192     return UnknownVal();
193 
194   if (isa<Loc>(lhs)) {
195     if (isa<Loc>(rhs))
196       return evalBinOpLL(state, op, cast<Loc>(lhs), cast<Loc>(rhs), type);
197 
198     return evalBinOpLN(state, op, cast<Loc>(lhs), cast<NonLoc>(rhs), type);
199   }
200 
201   if (isa<Loc>(rhs)) {
202     // Support pointer arithmetic where the addend is on the left
203     // and the pointer on the right.
204     assert(op == BO_Add);
205 
206     // Commute the operands.
207     return evalBinOpLN(state, op, cast<Loc>(rhs), cast<NonLoc>(lhs), type);
208   }
209 
210   return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type);
211 }
212 
213 DefinedOrUnknownSVal SValBuilder::evalEQ(const ProgramState *state,
214                                          DefinedOrUnknownSVal lhs,
215                                          DefinedOrUnknownSVal rhs) {
216   return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs,
217                                               Context.IntTy));
218 }
219 
220 // FIXME: should rewrite according to the cast kind.
221 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
222   if (val.isUnknownOrUndef() || castTy == originalTy)
223     return val;
224 
225   // For const casts, just propagate the value.
226   if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
227     if (Context.hasSameUnqualifiedType(castTy, originalTy))
228       return val;
229 
230   // Check for casts from pointers to integers.
231   if (castTy->isIntegerType() && Loc::isLocType(originalTy))
232     return evalCastFromLoc(cast<Loc>(val), castTy);
233 
234   // Check for casts from integers to pointers.
235   if (Loc::isLocType(castTy) && originalTy->isIntegerType()) {
236     if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
237       if (const MemRegion *R = LV->getLoc().getAsRegion()) {
238         StoreManager &storeMgr = StateMgr.getStoreManager();
239         R = storeMgr.castRegion(R, castTy);
240         return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
241       }
242       return LV->getLoc();
243     }
244     return dispatchCast(val, castTy);
245   }
246 
247   // Just pass through function and block pointers.
248   if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
249     assert(Loc::isLocType(castTy));
250     return val;
251   }
252 
253   // Check for casts from array type to another type.
254   if (originalTy->isArrayType()) {
255     // We will always decay to a pointer.
256     val = StateMgr.ArrayToPointer(cast<Loc>(val));
257 
258     // Are we casting from an array to a pointer?  If so just pass on
259     // the decayed value.
260     if (castTy->isPointerType())
261       return val;
262 
263     // Are we casting from an array to an integer?  If so, cast the decayed
264     // pointer value to an integer.
265     assert(castTy->isIntegerType());
266 
267     // FIXME: Keep these here for now in case we decide soon that we
268     // need the original decayed type.
269     //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
270     //    QualType pointerTy = C.getPointerType(elemTy);
271     return evalCastFromLoc(cast<Loc>(val), castTy);
272   }
273 
274   // Check for casts from a region to a specific type.
275   if (const MemRegion *R = val.getAsRegion()) {
276     // FIXME: We should handle the case where we strip off view layers to get
277     //  to a desugared type.
278 
279     if (!Loc::isLocType(castTy)) {
280       // FIXME: There can be gross cases where one casts the result of a function
281       // (that returns a pointer) to some other value that happens to fit
282       // within that pointer value.  We currently have no good way to
283       // model such operations.  When this happens, the underlying operation
284       // is that the caller is reasoning about bits.  Conceptually we are
285       // layering a "view" of a location on top of those bits.  Perhaps
286       // we need to be more lazy about mutual possible views, even on an
287       // SVal?  This may be necessary for bit-level reasoning as well.
288       return UnknownVal();
289     }
290 
291     // We get a symbolic function pointer for a dereference of a function
292     // pointer, but it is of function type. Example:
293 
294     //  struct FPRec {
295     //    void (*my_func)(int * x);
296     //  };
297     //
298     //  int bar(int x);
299     //
300     //  int f1_a(struct FPRec* foo) {
301     //    int x;
302     //    (*foo->my_func)(&x);
303     //    return bar(x)+1; // no-warning
304     //  }
305 
306     assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
307            originalTy->isBlockPointerType() || castTy->isReferenceType());
308 
309     StoreManager &storeMgr = StateMgr.getStoreManager();
310 
311     // Delegate to store manager to get the result of casting a region to a
312     // different type.  If the MemRegion* returned is NULL, this expression
313     // Evaluates to UnknownVal.
314     R = storeMgr.castRegion(R, castTy);
315     return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
316   }
317 
318   // Check for casts from integers to integers.
319   if (castTy->isIntegerType() && originalTy->isIntegerType())
320     return dispatchCast(val, castTy);
321 
322   return dispatchCast(val, castTy);
323 }
324