blob: 95829c2eab16c56307c049121c897741d7bcc361 [file] [log] [blame]
Ted Kremenek846eabd2010-12-01 21:28:31 +00001// SValBuilder.cpp - Basic class for all SValBuilder implementations -*- C++ -*-
Ted Kremenek32c3fa42009-07-21 21:03:30 +00002//
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//
Ted Kremenek846eabd2010-12-01 21:28:31 +000010// This file defines SValBuilder, the base class for all (complete) SValBuilder
Ted Kremenek32c3fa42009-07-21 21:03:30 +000011// implementations.
12//
13//===----------------------------------------------------------------------===//
14
Argyrios Kyrtzidis98cabba2010-12-22 18:51:49 +000015#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"
Ted Kremenek32c3fa42009-07-21 21:03:30 +000020
21using namespace clang;
22
Ted Kremenekc8413fd2010-12-02 07:49:45 +000023//===----------------------------------------------------------------------===//
24// Basic SVal creation.
25//===----------------------------------------------------------------------===//
26
27DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType T) {
28 if (Loc::IsLocType(T))
29 return makeNull();
30
31 if (T->isIntegerType())
32 return makeIntVal(0, T);
33
34 // FIXME: Handle floats.
35 // FIXME: Handle structs.
36 return UnknownVal();
37}
38
39
40NonLoc 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));
47}
48
49NonLoc 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));
54}
55
56
57SVal SValBuilder::convertToArrayIndex(SVal V) {
58 if (V.isUnknownOrUndef())
59 return V;
60
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())
65 return V;
66 }
67
68 return evalCastNL(cast<NonLoc>(V), ArrayIndexTy);
69}
70
71DefinedOrUnknownSVal
72SValBuilder::getRegionValueSymbolVal(const TypedRegion* R) {
73 QualType T = R->getValueType();
74
75 if (!SymbolManager::canSymbolicate(T))
76 return UnknownVal();
77
78 SymbolRef sym = SymMgr.getRegionValueSymbol(R);
79
80 if (Loc::IsLocType(T))
81 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
82
83 return nonloc::SymbolVal(sym);
84}
85
86DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag,
87 const Expr *E,
88 unsigned Count) {
89 QualType T = E->getType();
90
91 if (!SymbolManager::canSymbolicate(T))
92 return UnknownVal();
93
94 SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag);
95
96 if (Loc::IsLocType(T))
97 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
98
99 return nonloc::SymbolVal(sym);
100}
101
102DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag,
103 const Expr *E,
104 QualType T,
105 unsigned Count) {
106
107 if (!SymbolManager::canSymbolicate(T))
108 return UnknownVal();
109
110 SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag);
111
112 if (Loc::IsLocType(T))
113 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
114
115 return nonloc::SymbolVal(sym);
116}
117
118DefinedSVal SValBuilder::getMetadataSymbolVal(const void *SymbolTag,
119 const MemRegion *MR,
120 const Expr *E, QualType T,
121 unsigned Count) {
122 assert(SymbolManager::canSymbolicate(T) && "Invalid metadata symbol type");
123
124 SymbolRef sym = SymMgr.getMetadataSymbol(MR, E, T, Count, SymbolTag);
125
126 if (Loc::IsLocType(T))
127 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
128
129 return nonloc::SymbolVal(sym);
130}
131
132DefinedOrUnknownSVal
133SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
134 const TypedRegion *R) {
135 QualType T = R->getValueType();
136
137 if (!SymbolManager::canSymbolicate(T))
138 return UnknownVal();
139
140 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R);
141
142 if (Loc::IsLocType(T))
143 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
144
145 return nonloc::SymbolVal(sym);
146}
147
148DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl* FD) {
149 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD));
150}
151
152DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *D,
153 CanQualType locTy,
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);
159}
160
161//===----------------------------------------------------------------------===//
Ted Kremenekff4264d2009-08-25 18:44:25 +0000162
Ted Kremenek9c149532010-12-01 21:57:22 +0000163SVal SValBuilder::evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
Ted Kremenekff4264d2009-08-25 18:44:25 +0000164 SVal L, SVal R, QualType T) {
165
166 if (L.isUndef() || R.isUndef())
167 return UndefinedVal();
Mike Stump1eb44332009-09-09 15:08:12 +0000168
Ted Kremenekff4264d2009-08-25 18:44:25 +0000169 if (L.isUnknown() || R.isUnknown())
170 return UnknownVal();
Mike Stump1eb44332009-09-09 15:08:12 +0000171
Ted Kremenekff4264d2009-08-25 18:44:25 +0000172 if (isa<Loc>(L)) {
173 if (isa<Loc>(R))
Ted Kremenek9c149532010-12-01 21:57:22 +0000174 return evalBinOpLL(ST, Op, cast<Loc>(L), cast<Loc>(R), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000175
Ted Kremenek9c149532010-12-01 21:57:22 +0000176 return evalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000177 }
Mike Stump1eb44332009-09-09 15:08:12 +0000178
Ted Kremenekff4264d2009-08-25 18:44:25 +0000179 if (isa<Loc>(R)) {
Jordy Roseeac4a002010-06-28 08:26:15 +0000180 // Support pointer arithmetic where the addend is on the left
181 // and the pointer on the right.
John McCall2de56d12010-08-25 11:45:40 +0000182 assert(Op == BO_Add);
Mike Stump1eb44332009-09-09 15:08:12 +0000183
Ted Kremenekff4264d2009-08-25 18:44:25 +0000184 // Commute the operands.
Ted Kremenek9c149532010-12-01 21:57:22 +0000185 return evalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000186 }
187
Ted Kremenek9c149532010-12-01 21:57:22 +0000188 return evalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000189}
190
Ted Kremenek9c149532010-12-01 21:57:22 +0000191DefinedOrUnknownSVal SValBuilder::evalEQ(const GRState *ST,
Ted Kremenek5b9bd212009-09-11 22:07:28 +0000192 DefinedOrUnknownSVal L,
193 DefinedOrUnknownSVal R) {
Ted Kremenek9c149532010-12-01 21:57:22 +0000194 return cast<DefinedOrUnknownSVal>(evalBinOp(ST, BO_EQ, L, R,
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000195 Context.IntTy));
Ted Kremenek5b9bd212009-09-11 22:07:28 +0000196}
197
Zhongxing Xudc1ad2c2010-11-26 07:15:40 +0000198// FIXME: should rewrite according to the cast kind.
Ted Kremenek9c149532010-12-01 21:57:22 +0000199SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000200 if (val.isUnknownOrUndef() || castTy == originalTy)
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000201 return val;
Mike Stump1eb44332009-09-09 15:08:12 +0000202
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000203 // For const casts, just propagate the value.
Zhongxing Xu5ea95fc2010-01-05 09:27:03 +0000204 if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000205 if (Context.hasSameUnqualifiedType(castTy, originalTy))
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000206 return val;
Mike Stump1eb44332009-09-09 15:08:12 +0000207
Ted Kremenekf6817042010-02-02 21:11:40 +0000208 // Check for casts to real or complex numbers. We don't handle these at all
209 // right now.
210 if (castTy->isFloatingType() || castTy->isAnyComplexType())
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000211 return UnknownVal();
Ted Kremenekf6817042010-02-02 21:11:40 +0000212
213 // Check for casts from integers to integers.
Zhongxing Xu7b81e8f2010-01-14 03:45:06 +0000214 if (castTy->isIntegerType() && originalTy->isIntegerType())
Ted Kremenek9c149532010-12-01 21:57:22 +0000215 return evalCastNL(cast<NonLoc>(val), castTy);
Zhongxing Xu7b81e8f2010-01-14 03:45:06 +0000216
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000217 // Check for casts from pointers to integers.
218 if (castTy->isIntegerType() && Loc::IsLocType(originalTy))
Ted Kremenek9c149532010-12-01 21:57:22 +0000219 return evalCastL(cast<Loc>(val), castTy);
Mike Stump1eb44332009-09-09 15:08:12 +0000220
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000221 // Check for casts from integers to pointers.
222 if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
223 if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000224 if (const MemRegion *R = LV->getLoc().getAsRegion()) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000225 StoreManager &storeMgr = StateMgr.getStoreManager();
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000226 R = storeMgr.CastRegion(R, castTy);
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000227 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000228 }
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000229 return LV->getLoc();
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000230 }
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000231 goto DispatchCast;
232 }
Mike Stump1eb44332009-09-09 15:08:12 +0000233
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000234 // Just pass through function and block pointers.
235 if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
236 assert(Loc::IsLocType(castTy));
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000237 return val;
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000238 }
Mike Stump1eb44332009-09-09 15:08:12 +0000239
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000240 // Check for casts from array type to another type.
241 if (originalTy->isArrayType()) {
242 // We will always decay to a pointer.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000243 val = StateMgr.ArrayToPointer(cast<Loc>(val));
Mike Stump1eb44332009-09-09 15:08:12 +0000244
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000245 // Are we casting from an array to a pointer? If so just pass on
246 // the decayed value.
247 if (castTy->isPointerType())
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000248 return val;
Mike Stump1eb44332009-09-09 15:08:12 +0000249
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000250 // Are we casting from an array to an integer? If so, cast the decayed
251 // pointer value to an integer.
252 assert(castTy->isIntegerType());
Mike Stump1eb44332009-09-09 15:08:12 +0000253
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000254 // 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);
Ted Kremenek9c149532010-12-01 21:57:22 +0000258 return evalCastL(cast<Loc>(val), castTy);
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000259 }
Mike Stump1eb44332009-09-09 15:08:12 +0000260
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000261 // Check for casts from a region to a specific type.
262 if (const MemRegion *R = val.getAsRegion()) {
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000263 // FIXME: We should handle the case where we strip off view layers to get
264 // to a desugared type.
Mike Stump1eb44332009-09-09 15:08:12 +0000265
Ted Kremenek948163b2010-11-15 20:09:42 +0000266 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.
275 return UnknownVal();
276 }
277
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000278 // We get a symbolic function pointer for a dereference of a function
279 // pointer, but it is of function type. Example:
Mike Stump1eb44332009-09-09 15:08:12 +0000280
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000281 // struct FPRec {
Mike Stump1eb44332009-09-09 15:08:12 +0000282 // void (*my_func)(int * x);
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000283 // };
284 //
285 // int bar(int x);
286 //
287 // int f1_a(struct FPRec* foo) {
288 // int x;
289 // (*foo->my_func)(&x);
290 // return bar(x)+1; // no-warning
291 // }
Mike Stump1eb44332009-09-09 15:08:12 +0000292
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000293 assert(Loc::IsLocType(originalTy) || originalTy->isFunctionType() ||
294 originalTy->isBlockPointerType());
Mike Stump1eb44332009-09-09 15:08:12 +0000295
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000296 StoreManager &storeMgr = StateMgr.getStoreManager();
Mike Stump1eb44332009-09-09 15:08:12 +0000297
Zhongxing Xu09270cc2009-10-14 06:55:01 +0000298 // 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
Ted Kremenek9c149532010-12-01 21:57:22 +0000300 // Evaluates to UnknownVal.
Zhongxing Xu09270cc2009-10-14 06:55:01 +0000301 R = storeMgr.CastRegion(R, castTy);
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000302 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000303 }
Mike Stump1eb44332009-09-09 15:08:12 +0000304
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000305DispatchCast:
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000306 // All other cases.
Ted Kremenek9c149532010-12-01 21:57:22 +0000307 return isa<Loc>(val) ? evalCastL(cast<Loc>(val), castTy)
308 : evalCastNL(cast<NonLoc>(val), castTy);
Ted Kremenek5b9bd212009-09-11 22:07:28 +0000309}