1 // SValBuilder.cpp - Basic class for all SValBuilder implementations -*- C++ -*-
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines SValBuilder, the base class for all (complete) SValBuilder
13 //===----------------------------------------------------------------------===//
15 #include "clang/GR/PathSensitive/MemRegion.h"
16 #include "clang/GR/PathSensitive/SVals.h"
17 #include "clang/GR/PathSensitive/SValBuilder.h"
18 #include "clang/GR/PathSensitive/GRState.h"
19 #include "clang/GR/PathSensitive/BasicValueFactory.h"
21 using namespace clang
;
23 //===----------------------------------------------------------------------===//
24 // Basic SVal creation.
25 //===----------------------------------------------------------------------===//
27 DefinedOrUnknownSVal
SValBuilder::makeZeroVal(QualType T
) {
28 if (Loc::IsLocType(T
))
31 if (T
->isIntegerType())
32 return makeIntVal(0, T
);
34 // FIXME: Handle floats.
35 // FIXME: Handle structs.
40 NonLoc
SValBuilder::makeNonLoc(const SymExpr
*lhs
, BinaryOperator::Opcode op
,
41 const llvm::APSInt
& v
, QualType T
) {
42 // The Environment ensures we always get a persistent APSInt in
43 // BasicValueFactory, so we don't need to get the APSInt from
44 // BasicValueFactory again.
45 assert(!Loc::IsLocType(T
));
46 return nonloc::SymExprVal(SymMgr
.getSymIntExpr(lhs
, op
, v
, T
));
49 NonLoc
SValBuilder::makeNonLoc(const SymExpr
*lhs
, BinaryOperator::Opcode op
,
50 const SymExpr
*rhs
, QualType T
) {
51 assert(SymMgr
.getType(lhs
) == SymMgr
.getType(rhs
));
52 assert(!Loc::IsLocType(T
));
53 return nonloc::SymExprVal(SymMgr
.getSymSymExpr(lhs
, op
, rhs
, T
));
57 SVal
SValBuilder::convertToArrayIndex(SVal V
) {
58 if (V
.isUnknownOrUndef())
61 // Common case: we have an appropriately sized integer.
62 if (nonloc::ConcreteInt
* CI
= dyn_cast
<nonloc::ConcreteInt
>(&V
)) {
63 const llvm::APSInt
& I
= CI
->getValue();
64 if (I
.getBitWidth() == ArrayIndexWidth
&& I
.isSigned())
68 return evalCastNL(cast
<NonLoc
>(V
), ArrayIndexTy
);
72 SValBuilder::getRegionValueSymbolVal(const TypedRegion
* R
) {
73 QualType T
= R
->getValueType();
75 if (!SymbolManager::canSymbolicate(T
))
78 SymbolRef sym
= SymMgr
.getRegionValueSymbol(R
);
80 if (Loc::IsLocType(T
))
81 return loc::MemRegionVal(MemMgr
.getSymbolicRegion(sym
));
83 return nonloc::SymbolVal(sym
);
86 DefinedOrUnknownSVal
SValBuilder::getConjuredSymbolVal(const void *SymbolTag
,
89 QualType T
= E
->getType();
91 if (!SymbolManager::canSymbolicate(T
))
94 SymbolRef sym
= SymMgr
.getConjuredSymbol(E
, Count
, SymbolTag
);
96 if (Loc::IsLocType(T
))
97 return loc::MemRegionVal(MemMgr
.getSymbolicRegion(sym
));
99 return nonloc::SymbolVal(sym
);
102 DefinedOrUnknownSVal
SValBuilder::getConjuredSymbolVal(const void *SymbolTag
,
107 if (!SymbolManager::canSymbolicate(T
))
110 SymbolRef sym
= SymMgr
.getConjuredSymbol(E
, T
, Count
, SymbolTag
);
112 if (Loc::IsLocType(T
))
113 return loc::MemRegionVal(MemMgr
.getSymbolicRegion(sym
));
115 return nonloc::SymbolVal(sym
);
118 DefinedSVal
SValBuilder::getMetadataSymbolVal(const void *SymbolTag
,
120 const Expr
*E
, QualType T
,
122 assert(SymbolManager::canSymbolicate(T
) && "Invalid metadata symbol type");
124 SymbolRef sym
= SymMgr
.getMetadataSymbol(MR
, E
, T
, Count
, SymbolTag
);
126 if (Loc::IsLocType(T
))
127 return loc::MemRegionVal(MemMgr
.getSymbolicRegion(sym
));
129 return nonloc::SymbolVal(sym
);
133 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol
,
134 const TypedRegion
*R
) {
135 QualType T
= R
->getValueType();
137 if (!SymbolManager::canSymbolicate(T
))
140 SymbolRef sym
= SymMgr
.getDerivedSymbol(parentSymbol
, R
);
142 if (Loc::IsLocType(T
))
143 return loc::MemRegionVal(MemMgr
.getSymbolicRegion(sym
));
145 return nonloc::SymbolVal(sym
);
148 DefinedSVal
SValBuilder::getFunctionPointer(const FunctionDecl
* FD
) {
149 return loc::MemRegionVal(MemMgr
.getFunctionTextRegion(FD
));
152 DefinedSVal
SValBuilder::getBlockPointer(const BlockDecl
*D
,
154 const LocationContext
*LC
) {
155 const BlockTextRegion
*BC
=
156 MemMgr
.getBlockTextRegion(D
, locTy
, LC
->getAnalysisContext());
157 const BlockDataRegion
*BD
= MemMgr
.getBlockDataRegion(BC
, LC
);
158 return loc::MemRegionVal(BD
);
161 //===----------------------------------------------------------------------===//
163 SVal
SValBuilder::evalBinOp(const GRState
*ST
, BinaryOperator::Opcode Op
,
164 SVal L
, SVal R
, QualType T
) {
166 if (L
.isUndef() || R
.isUndef())
167 return UndefinedVal();
169 if (L
.isUnknown() || R
.isUnknown())
174 return evalBinOpLL(ST
, Op
, cast
<Loc
>(L
), cast
<Loc
>(R
), T
);
176 return evalBinOpLN(ST
, Op
, cast
<Loc
>(L
), cast
<NonLoc
>(R
), T
);
180 // Support pointer arithmetic where the addend is on the left
181 // and the pointer on the right.
182 assert(Op
== BO_Add
);
184 // Commute the operands.
185 return evalBinOpLN(ST
, Op
, cast
<Loc
>(R
), cast
<NonLoc
>(L
), T
);
188 return evalBinOpNN(ST
, Op
, cast
<NonLoc
>(L
), cast
<NonLoc
>(R
), T
);
191 DefinedOrUnknownSVal
SValBuilder::evalEQ(const GRState
*ST
,
192 DefinedOrUnknownSVal L
,
193 DefinedOrUnknownSVal R
) {
194 return cast
<DefinedOrUnknownSVal
>(evalBinOp(ST
, BO_EQ
, L
, R
,
198 // FIXME: should rewrite according to the cast kind.
199 SVal
SValBuilder::evalCast(SVal val
, QualType castTy
, QualType originalTy
) {
200 if (val
.isUnknownOrUndef() || castTy
== originalTy
)
203 // For const casts, just propagate the value.
204 if (!castTy
->isVariableArrayType() && !originalTy
->isVariableArrayType())
205 if (Context
.hasSameUnqualifiedType(castTy
, originalTy
))
208 // Check for casts to real or complex numbers. We don't handle these at all
210 if (castTy
->isFloatingType() || castTy
->isAnyComplexType())
213 // Check for casts from integers to integers.
214 if (castTy
->isIntegerType() && originalTy
->isIntegerType())
215 return evalCastNL(cast
<NonLoc
>(val
), castTy
);
217 // Check for casts from pointers to integers.
218 if (castTy
->isIntegerType() && Loc::IsLocType(originalTy
))
219 return evalCastL(cast
<Loc
>(val
), castTy
);
221 // Check for casts from integers to pointers.
222 if (Loc::IsLocType(castTy
) && originalTy
->isIntegerType()) {
223 if (nonloc::LocAsInteger
*LV
= dyn_cast
<nonloc::LocAsInteger
>(&val
)) {
224 if (const MemRegion
*R
= LV
->getLoc().getAsRegion()) {
225 StoreManager
&storeMgr
= StateMgr
.getStoreManager();
226 R
= storeMgr
.CastRegion(R
, castTy
);
227 return R
? SVal(loc::MemRegionVal(R
)) : UnknownVal();
234 // Just pass through function and block pointers.
235 if (originalTy
->isBlockPointerType() || originalTy
->isFunctionPointerType()) {
236 assert(Loc::IsLocType(castTy
));
240 // Check for casts from array type to another type.
241 if (originalTy
->isArrayType()) {
242 // We will always decay to a pointer.
243 val
= StateMgr
.ArrayToPointer(cast
<Loc
>(val
));
245 // Are we casting from an array to a pointer? If so just pass on
246 // the decayed value.
247 if (castTy
->isPointerType())
250 // Are we casting from an array to an integer? If so, cast the decayed
251 // pointer value to an integer.
252 assert(castTy
->isIntegerType());
254 // FIXME: Keep these here for now in case we decide soon that we
255 // need the original decayed type.
256 // QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
257 // QualType pointerTy = C.getPointerType(elemTy);
258 return evalCastL(cast
<Loc
>(val
), castTy
);
261 // Check for casts from a region to a specific type.
262 if (const MemRegion
*R
= val
.getAsRegion()) {
263 // FIXME: We should handle the case where we strip off view layers to get
264 // to a desugared type.
266 if (!Loc::IsLocType(castTy
)) {
267 // FIXME: There can be gross cases where one casts the result of a function
268 // (that returns a pointer) to some other value that happens to fit
269 // within that pointer value. We currently have no good way to
270 // model such operations. When this happens, the underlying operation
271 // is that the caller is reasoning about bits. Conceptually we are
272 // layering a "view" of a location on top of those bits. Perhaps
273 // we need to be more lazy about mutual possible views, even on an
274 // SVal? This may be necessary for bit-level reasoning as well.
278 // We get a symbolic function pointer for a dereference of a function
279 // pointer, but it is of function type. Example:
282 // void (*my_func)(int * x);
287 // int f1_a(struct FPRec* foo) {
289 // (*foo->my_func)(&x);
290 // return bar(x)+1; // no-warning
293 assert(Loc::IsLocType(originalTy
) || originalTy
->isFunctionType() ||
294 originalTy
->isBlockPointerType());
296 StoreManager
&storeMgr
= StateMgr
.getStoreManager();
298 // Delegate to store manager to get the result of casting a region to a
299 // different type. If the MemRegion* returned is NULL, this expression
300 // Evaluates to UnknownVal.
301 R
= storeMgr
.CastRegion(R
, castTy
);
302 return R
? SVal(loc::MemRegionVal(R
)) : UnknownVal();
307 return isa
<Loc
>(val
) ? evalCastL(cast
<Loc
>(val
), castTy
)
308 : evalCastNL(cast
<NonLoc
>(val
), castTy
);