blob: f87fb7ee1e4f45fa18e05854d10d68bc874b9190 [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
Ted Kremenek21142582010-12-23 19:38:26 +000015#include "clang/StaticAnalyzer/PathSensitive/MemRegion.h"
16#include "clang/StaticAnalyzer/PathSensitive/SVals.h"
17#include "clang/StaticAnalyzer/PathSensitive/SValBuilder.h"
18#include "clang/StaticAnalyzer/PathSensitive/GRState.h"
19#include "clang/StaticAnalyzer/PathSensitive/BasicValueFactory.h"
Ted Kremenek32c3fa42009-07-21 21:03:30 +000020
21using namespace clang;
Ted Kremenek9ef65372010-12-23 07:20:52 +000022using namespace ento;
Ted Kremenek32c3fa42009-07-21 21:03:30 +000023
Ted Kremenekc8413fd2010-12-02 07:49:45 +000024//===----------------------------------------------------------------------===//
25// Basic SVal creation.
26//===----------------------------------------------------------------------===//
27
28DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType T) {
29 if (Loc::IsLocType(T))
30 return makeNull();
31
32 if (T->isIntegerType())
33 return makeIntVal(0, T);
34
35 // FIXME: Handle floats.
36 // FIXME: Handle structs.
37 return UnknownVal();
38}
39
40
41NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
42 const llvm::APSInt& v, QualType T) {
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(!Loc::IsLocType(T));
47 return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
48}
49
50NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
51 const SymExpr *rhs, QualType T) {
52 assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
53 assert(!Loc::IsLocType(T));
54 return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
55}
56
57
58SVal SValBuilder::convertToArrayIndex(SVal V) {
59 if (V.isUnknownOrUndef())
60 return V;
61
62 // Common case: we have an appropriately sized integer.
63 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) {
64 const llvm::APSInt& I = CI->getValue();
65 if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
66 return V;
67 }
68
69 return evalCastNL(cast<NonLoc>(V), ArrayIndexTy);
70}
71
72DefinedOrUnknownSVal
73SValBuilder::getRegionValueSymbolVal(const TypedRegion* R) {
74 QualType T = R->getValueType();
75
76 if (!SymbolManager::canSymbolicate(T))
77 return UnknownVal();
78
79 SymbolRef sym = SymMgr.getRegionValueSymbol(R);
80
81 if (Loc::IsLocType(T))
82 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
83
84 return nonloc::SymbolVal(sym);
85}
86
87DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag,
88 const Expr *E,
89 unsigned Count) {
90 QualType T = E->getType();
91
92 if (!SymbolManager::canSymbolicate(T))
93 return UnknownVal();
94
95 SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag);
96
97 if (Loc::IsLocType(T))
98 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
99
100 return nonloc::SymbolVal(sym);
101}
102
103DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag,
104 const Expr *E,
105 QualType T,
106 unsigned Count) {
107
108 if (!SymbolManager::canSymbolicate(T))
109 return UnknownVal();
110
111 SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag);
112
113 if (Loc::IsLocType(T))
114 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
115
116 return nonloc::SymbolVal(sym);
117}
118
119DefinedSVal SValBuilder::getMetadataSymbolVal(const void *SymbolTag,
120 const MemRegion *MR,
121 const Expr *E, QualType T,
122 unsigned Count) {
123 assert(SymbolManager::canSymbolicate(T) && "Invalid metadata symbol type");
124
125 SymbolRef sym = SymMgr.getMetadataSymbol(MR, E, T, Count, SymbolTag);
126
127 if (Loc::IsLocType(T))
128 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
129
130 return nonloc::SymbolVal(sym);
131}
132
133DefinedOrUnknownSVal
134SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
135 const TypedRegion *R) {
136 QualType T = R->getValueType();
137
138 if (!SymbolManager::canSymbolicate(T))
139 return UnknownVal();
140
141 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R);
142
143 if (Loc::IsLocType(T))
144 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
145
146 return nonloc::SymbolVal(sym);
147}
148
149DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl* FD) {
150 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD));
151}
152
153DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *D,
154 CanQualType locTy,
155 const LocationContext *LC) {
156 const BlockTextRegion *BC =
157 MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext());
158 const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC);
159 return loc::MemRegionVal(BD);
160}
161
162//===----------------------------------------------------------------------===//
Ted Kremenekff4264d2009-08-25 18:44:25 +0000163
Ted Kremenek9c149532010-12-01 21:57:22 +0000164SVal SValBuilder::evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
Ted Kremenekff4264d2009-08-25 18:44:25 +0000165 SVal L, SVal R, QualType T) {
166
167 if (L.isUndef() || R.isUndef())
168 return UndefinedVal();
Mike Stump1eb44332009-09-09 15:08:12 +0000169
Ted Kremenekff4264d2009-08-25 18:44:25 +0000170 if (L.isUnknown() || R.isUnknown())
171 return UnknownVal();
Mike Stump1eb44332009-09-09 15:08:12 +0000172
Ted Kremenekff4264d2009-08-25 18:44:25 +0000173 if (isa<Loc>(L)) {
174 if (isa<Loc>(R))
Ted Kremenek9c149532010-12-01 21:57:22 +0000175 return evalBinOpLL(ST, Op, cast<Loc>(L), cast<Loc>(R), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000176
Ted Kremenek9c149532010-12-01 21:57:22 +0000177 return evalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000178 }
Mike Stump1eb44332009-09-09 15:08:12 +0000179
Ted Kremenekff4264d2009-08-25 18:44:25 +0000180 if (isa<Loc>(R)) {
Jordy Roseeac4a002010-06-28 08:26:15 +0000181 // Support pointer arithmetic where the addend is on the left
182 // and the pointer on the right.
John McCall2de56d12010-08-25 11:45:40 +0000183 assert(Op == BO_Add);
Mike Stump1eb44332009-09-09 15:08:12 +0000184
Ted Kremenekff4264d2009-08-25 18:44:25 +0000185 // Commute the operands.
Ted Kremenek9c149532010-12-01 21:57:22 +0000186 return evalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000187 }
188
Ted Kremenek9c149532010-12-01 21:57:22 +0000189 return evalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
Ted Kremenekff4264d2009-08-25 18:44:25 +0000190}
191
Ted Kremenek9c149532010-12-01 21:57:22 +0000192DefinedOrUnknownSVal SValBuilder::evalEQ(const GRState *ST,
Ted Kremenek5b9bd212009-09-11 22:07:28 +0000193 DefinedOrUnknownSVal L,
194 DefinedOrUnknownSVal R) {
Ted Kremenek9c149532010-12-01 21:57:22 +0000195 return cast<DefinedOrUnknownSVal>(evalBinOp(ST, BO_EQ, L, R,
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000196 Context.IntTy));
Ted Kremenek5b9bd212009-09-11 22:07:28 +0000197}
198
Zhongxing Xudc1ad2c2010-11-26 07:15:40 +0000199// FIXME: should rewrite according to the cast kind.
Ted Kremenek9c149532010-12-01 21:57:22 +0000200SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000201 if (val.isUnknownOrUndef() || castTy == originalTy)
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000202 return val;
Mike Stump1eb44332009-09-09 15:08:12 +0000203
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000204 // For const casts, just propagate the value.
Zhongxing Xu5ea95fc2010-01-05 09:27:03 +0000205 if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000206 if (Context.hasSameUnqualifiedType(castTy, originalTy))
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000207 return val;
Mike Stump1eb44332009-09-09 15:08:12 +0000208
Ted Kremenekf6817042010-02-02 21:11:40 +0000209 // Check for casts to real or complex numbers. We don't handle these at all
210 // right now.
211 if (castTy->isFloatingType() || castTy->isAnyComplexType())
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000212 return UnknownVal();
Ted Kremenekf6817042010-02-02 21:11:40 +0000213
214 // Check for casts from integers to integers.
Zhongxing Xu7b81e8f2010-01-14 03:45:06 +0000215 if (castTy->isIntegerType() && originalTy->isIntegerType())
Ted Kremenek9c149532010-12-01 21:57:22 +0000216 return evalCastNL(cast<NonLoc>(val), castTy);
Zhongxing Xu7b81e8f2010-01-14 03:45:06 +0000217
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000218 // Check for casts from pointers to integers.
219 if (castTy->isIntegerType() && Loc::IsLocType(originalTy))
Ted Kremenek9c149532010-12-01 21:57:22 +0000220 return evalCastL(cast<Loc>(val), castTy);
Mike Stump1eb44332009-09-09 15:08:12 +0000221
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000222 // Check for casts from integers to pointers.
223 if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
224 if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000225 if (const MemRegion *R = LV->getLoc().getAsRegion()) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000226 StoreManager &storeMgr = StateMgr.getStoreManager();
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000227 R = storeMgr.CastRegion(R, castTy);
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000228 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000229 }
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000230 return LV->getLoc();
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000231 }
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000232 goto DispatchCast;
233 }
Mike Stump1eb44332009-09-09 15:08:12 +0000234
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000235 // Just pass through function and block pointers.
236 if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
237 assert(Loc::IsLocType(castTy));
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000238 return val;
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000239 }
Mike Stump1eb44332009-09-09 15:08:12 +0000240
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000241 // Check for casts from array type to another type.
242 if (originalTy->isArrayType()) {
243 // We will always decay to a pointer.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000244 val = StateMgr.ArrayToPointer(cast<Loc>(val));
Mike Stump1eb44332009-09-09 15:08:12 +0000245
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000246 // Are we casting from an array to a pointer? If so just pass on
247 // the decayed value.
248 if (castTy->isPointerType())
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000249 return val;
Mike Stump1eb44332009-09-09 15:08:12 +0000250
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000251 // Are we casting from an array to an integer? If so, cast the decayed
252 // pointer value to an integer.
253 assert(castTy->isIntegerType());
Mike Stump1eb44332009-09-09 15:08:12 +0000254
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000255 // FIXME: Keep these here for now in case we decide soon that we
256 // need the original decayed type.
257 // QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
258 // QualType pointerTy = C.getPointerType(elemTy);
Ted Kremenek9c149532010-12-01 21:57:22 +0000259 return evalCastL(cast<Loc>(val), castTy);
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000260 }
Mike Stump1eb44332009-09-09 15:08:12 +0000261
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000262 // Check for casts from a region to a specific type.
263 if (const MemRegion *R = val.getAsRegion()) {
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000264 // FIXME: We should handle the case where we strip off view layers to get
265 // to a desugared type.
Mike Stump1eb44332009-09-09 15:08:12 +0000266
Ted Kremenek948163b2010-11-15 20:09:42 +0000267 if (!Loc::IsLocType(castTy)) {
268 // FIXME: There can be gross cases where one casts the result of a function
269 // (that returns a pointer) to some other value that happens to fit
270 // within that pointer value. We currently have no good way to
271 // model such operations. When this happens, the underlying operation
272 // is that the caller is reasoning about bits. Conceptually we are
273 // layering a "view" of a location on top of those bits. Perhaps
274 // we need to be more lazy about mutual possible views, even on an
275 // SVal? This may be necessary for bit-level reasoning as well.
276 return UnknownVal();
277 }
278
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000279 // We get a symbolic function pointer for a dereference of a function
280 // pointer, but it is of function type. Example:
Mike Stump1eb44332009-09-09 15:08:12 +0000281
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000282 // struct FPRec {
Mike Stump1eb44332009-09-09 15:08:12 +0000283 // void (*my_func)(int * x);
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000284 // };
285 //
286 // int bar(int x);
287 //
288 // int f1_a(struct FPRec* foo) {
289 // int x;
290 // (*foo->my_func)(&x);
291 // return bar(x)+1; // no-warning
292 // }
Mike Stump1eb44332009-09-09 15:08:12 +0000293
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000294 assert(Loc::IsLocType(originalTy) || originalTy->isFunctionType() ||
295 originalTy->isBlockPointerType());
Mike Stump1eb44332009-09-09 15:08:12 +0000296
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000297 StoreManager &storeMgr = StateMgr.getStoreManager();
Mike Stump1eb44332009-09-09 15:08:12 +0000298
Zhongxing Xu09270cc2009-10-14 06:55:01 +0000299 // Delegate to store manager to get the result of casting a region to a
300 // different type. If the MemRegion* returned is NULL, this expression
Ted Kremenek9c149532010-12-01 21:57:22 +0000301 // Evaluates to UnknownVal.
Zhongxing Xu09270cc2009-10-14 06:55:01 +0000302 R = storeMgr.CastRegion(R, castTy);
Zhongxing Xu814e6b92010-02-04 04:56:43 +0000303 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000304 }
Mike Stump1eb44332009-09-09 15:08:12 +0000305
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000306DispatchCast:
Ted Kremenek5bbc8e72009-12-23 02:52:14 +0000307 // All other cases.
Ted Kremenek9c149532010-12-01 21:57:22 +0000308 return isa<Loc>(val) ? evalCastL(cast<Loc>(val), castTy)
309 : evalCastNL(cast<NonLoc>(val), castTy);
Ted Kremenek5b9bd212009-09-11 22:07:28 +0000310}