blob: 5b7041bc43cdd5046a1c38268086c0e2b80cbde5 [file] [log] [blame]
Ted Kremenek8ad19872008-03-07 20:13:31 +00001//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- C++ -*-//
Ted Kremenek94e915e2008-02-16 01:12:31 +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 Kremenek8ad19872008-03-07 20:13:31 +000010// This file defines BasicValueFactory, a class that manages the lifetime
11// of APSInt objects and symbolic constraints used by GRExprEngine
12// and related classes.
Ted Kremenek94e915e2008-02-16 01:12:31 +000013//
14//===----------------------------------------------------------------------===//
15
Ted Kremenek8ad19872008-03-07 20:13:31 +000016#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
Ted Kremenek94e915e2008-02-16 01:12:31 +000017
18using namespace clang;
19
Zhongxing Xu277884f2008-10-30 04:58:00 +000020void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
Ted Kremenek5e7a4b82008-10-30 17:44:46 +000021 llvm::ImmutableList<SVal> L) {
Zhongxing Xu277884f2008-10-30 04:58:00 +000022 T.Profile(ID);
Ted Kremenek5e7a4b82008-10-30 17:44:46 +000023 ID.AddPointer(L.getInternalPointer());
Zhongxing Xu277884f2008-10-30 04:58:00 +000024}
25
Zhongxing Xu097fc982008-10-17 05:57:07 +000026typedef std::pair<SVal, uintptr_t> SValData;
27typedef std::pair<SVal, SVal> SValPair;
Ted Kremenekc4385b42008-04-29 23:24:44 +000028
Ted Kremenekfe1a0b12008-04-22 21:10:18 +000029namespace llvm {
Zhongxing Xu097fc982008-10-17 05:57:07 +000030template<> struct FoldingSetTrait<SValData> {
31 static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenekfe1a0b12008-04-22 21:10:18 +000032 X.first.Profile(ID);
Ted Kremenek465f25a2008-04-29 22:17:41 +000033 ID.AddPointer( (void*) X.second);
Ted Kremenekfe1a0b12008-04-22 21:10:18 +000034 }
35};
Ted Kremenekc4385b42008-04-29 23:24:44 +000036
Zhongxing Xu097fc982008-10-17 05:57:07 +000037template<> struct FoldingSetTrait<SValPair> {
38 static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenekc4385b42008-04-29 23:24:44 +000039 X.first.Profile(ID);
40 X.second.Profile(ID);
41 }
42};
Ted Kremenekfe1a0b12008-04-22 21:10:18 +000043}
44
Zhongxing Xu097fc982008-10-17 05:57:07 +000045typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
46 PersistentSValsTy;
Ted Kremenekfe1a0b12008-04-22 21:10:18 +000047
Zhongxing Xu097fc982008-10-17 05:57:07 +000048typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
49 PersistentSValPairsTy;
Ted Kremenekc4385b42008-04-29 23:24:44 +000050
Ted Kremenek8ad19872008-03-07 20:13:31 +000051BasicValueFactory::~BasicValueFactory() {
Ted Kremenek94e915e2008-02-16 01:12:31 +000052 // Note that the dstor for the contents of APSIntSet will never be called,
53 // so we iterate over the set and invoke the dstor for each APSInt. This
54 // frees an aux. memory allocated to represent very large constants.
55 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
56 I->getValue().~APSInt();
Ted Kremenekfe1a0b12008-04-22 21:10:18 +000057
Zhongxing Xu097fc982008-10-17 05:57:07 +000058 delete (PersistentSValsTy*) PersistentSVals;
59 delete (PersistentSValPairsTy*) PersistentSValPairs;
Ted Kremenek94e915e2008-02-16 01:12:31 +000060}
61
Ted Kremenek8ad19872008-03-07 20:13:31 +000062const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
Ted Kremenek94e915e2008-02-16 01:12:31 +000063 llvm::FoldingSetNodeID ID;
64 void* InsertPos;
65 typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
66
67 X.Profile(ID);
68 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
69
70 if (!P) {
71 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
72 new (P) FoldNodeTy(X);
73 APSIntSet.InsertNode(P, InsertPos);
74 }
75
76 return *P;
77}
78
Ted Kremenek8ad19872008-03-07 20:13:31 +000079const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
Ted Kremenek94e915e2008-02-16 01:12:31 +000080 bool isUnsigned) {
81 llvm::APSInt V(BitWidth, isUnsigned);
82 V = X;
83 return getValue(V);
84}
85
Ted Kremenek8ad19872008-03-07 20:13:31 +000086const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
Ted Kremenek94e915e2008-02-16 01:12:31 +000087
Chris Lattner8cd0e932008-03-05 18:54:05 +000088 unsigned bits = Ctx.getTypeSize(T);
Ted Kremenek94e915e2008-02-16 01:12:31 +000089 llvm::APSInt V(bits, T->isUnsignedIntegerType());
90 V = X;
91 return getValue(V);
92}
93
94const SymIntConstraint&
Ted Kremenek8ad19872008-03-07 20:13:31 +000095BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
Ted Kremenek94e915e2008-02-16 01:12:31 +000096 const llvm::APSInt& V) {
97
98 llvm::FoldingSetNodeID ID;
99 SymIntConstraint::Profile(ID, sym, Op, V);
100 void* InsertPos;
101
102 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
103
104 if (!C) {
105 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
106 new (C) SymIntConstraint(sym, Op, V);
107 SymIntCSet.InsertNode(C, InsertPos);
108 }
109
110 return *C;
111}
112
Zhongxing Xu277884f2008-10-30 04:58:00 +0000113const CompoundValData*
Ted Kremenek5e7a4b82008-10-30 17:44:46 +0000114BasicValueFactory::getCompoundValData(QualType T,
115 llvm::ImmutableList<SVal> Vals) {
116
Zhongxing Xu277884f2008-10-30 04:58:00 +0000117 llvm::FoldingSetNodeID ID;
Ted Kremenek5e7a4b82008-10-30 17:44:46 +0000118 CompoundValData::Profile(ID, T, Vals);
Zhongxing Xu277884f2008-10-30 04:58:00 +0000119 void* InsertPos;
120
121 CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
122
123 if (!D) {
124 D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
Ted Kremenek5e7a4b82008-10-30 17:44:46 +0000125 new (D) CompoundValData(T, Vals);
Zhongxing Xu277884f2008-10-30 04:58:00 +0000126 CompoundValDataSet.InsertNode(D, InsertPos);
127 }
128
129 return D;
130}
131
Ted Kremenekc2d07202008-02-28 20:32:03 +0000132const llvm::APSInt*
Ted Kremenek8ad19872008-03-07 20:13:31 +0000133BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
Ted Kremenek94e915e2008-02-16 01:12:31 +0000134 const llvm::APSInt& V1, const llvm::APSInt& V2) {
135
136 switch (Op) {
137 default:
138 assert (false && "Invalid Opcode.");
139
140 case BinaryOperator::Mul:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000141 return &getValue( V1 * V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000142
143 case BinaryOperator::Div:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000144 return &getValue( V1 / V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000145
146 case BinaryOperator::Rem:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000147 return &getValue( V1 % V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000148
149 case BinaryOperator::Add:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000150 return &getValue( V1 + V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000151
152 case BinaryOperator::Sub:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000153 return &getValue( V1 - V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000154
Ted Kremenekc2d07202008-02-28 20:32:03 +0000155 case BinaryOperator::Shl: {
156
157 // FIXME: This logic should probably go higher up, where we can
158 // test these conditions symbolically.
Ted Kremenek94e915e2008-02-16 01:12:31 +0000159
Ted Kremenekc2d07202008-02-28 20:32:03 +0000160 // FIXME: Expand these checks to include all undefined behavior.
161
162 if (V2.isSigned() && V2.isNegative())
163 return NULL;
164
165 uint64_t Amt = V2.getZExtValue();
166
167 if (Amt > V1.getBitWidth())
168 return NULL;
169
170 return &getValue( V1.operator<<( (unsigned) Amt ));
171 }
172
173 case BinaryOperator::Shr: {
174
175 // FIXME: This logic should probably go higher up, where we can
176 // test these conditions symbolically.
177
178 // FIXME: Expand these checks to include all undefined behavior.
179
180 if (V2.isSigned() && V2.isNegative())
181 return NULL;
182
183 uint64_t Amt = V2.getZExtValue();
184
185 if (Amt > V1.getBitWidth())
186 return NULL;
187
188 return &getValue( V1.operator>>( (unsigned) Amt ));
189 }
Ted Kremenek94e915e2008-02-16 01:12:31 +0000190
191 case BinaryOperator::LT:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000192 return &getTruthValue( V1 < V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000193
194 case BinaryOperator::GT:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000195 return &getTruthValue( V1 > V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000196
197 case BinaryOperator::LE:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000198 return &getTruthValue( V1 <= V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000199
200 case BinaryOperator::GE:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000201 return &getTruthValue( V1 >= V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000202
203 case BinaryOperator::EQ:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000204 return &getTruthValue( V1 == V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000205
206 case BinaryOperator::NE:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000207 return &getTruthValue( V1 != V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000208
209 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
210
211 case BinaryOperator::And:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000212 return &getValue( V1 & V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000213
214 case BinaryOperator::Or:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000215 return &getValue( V1 | V2 );
Ted Kremenek7c79a792008-02-19 20:53:37 +0000216
217 case BinaryOperator::Xor:
Ted Kremenekc2d07202008-02-28 20:32:03 +0000218 return &getValue( V1 ^ V2 );
Ted Kremenek94e915e2008-02-16 01:12:31 +0000219 }
220}
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000221
222
Zhongxing Xu097fc982008-10-17 05:57:07 +0000223const std::pair<SVal, uintptr_t>&
224BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000225
226 // Lazily create the folding set.
Zhongxing Xu097fc982008-10-17 05:57:07 +0000227 if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000228
229 llvm::FoldingSetNodeID ID;
230 void* InsertPos;
231 V.Profile(ID);
Ted Kremenek465f25a2008-04-29 22:17:41 +0000232 ID.AddPointer((void*) Data);
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000233
Zhongxing Xu097fc982008-10-17 05:57:07 +0000234 PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000235
Zhongxing Xu097fc982008-10-17 05:57:07 +0000236 typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000237 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
238
239 if (!P) {
240 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
Ted Kremenek465f25a2008-04-29 22:17:41 +0000241 new (P) FoldNodeTy(std::make_pair(V, Data));
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000242 Map.InsertNode(P, InsertPos);
243 }
244
Ted Kremenek465f25a2008-04-29 22:17:41 +0000245 return P->getValue();
Ted Kremenekfe1a0b12008-04-22 21:10:18 +0000246}
Ted Kremenekc4385b42008-04-29 23:24:44 +0000247
Zhongxing Xu097fc982008-10-17 05:57:07 +0000248const std::pair<SVal, SVal>&
249BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
Ted Kremenekc4385b42008-04-29 23:24:44 +0000250
251 // Lazily create the folding set.
Zhongxing Xu097fc982008-10-17 05:57:07 +0000252 if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
Ted Kremenekc4385b42008-04-29 23:24:44 +0000253
254 llvm::FoldingSetNodeID ID;
255 void* InsertPos;
256 V1.Profile(ID);
257 V2.Profile(ID);
258
Zhongxing Xu097fc982008-10-17 05:57:07 +0000259 PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
Ted Kremenekc4385b42008-04-29 23:24:44 +0000260
Zhongxing Xu097fc982008-10-17 05:57:07 +0000261 typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
Ted Kremenekc4385b42008-04-29 23:24:44 +0000262 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
263
264 if (!P) {
265 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
266 new (P) FoldNodeTy(std::make_pair(V1, V2));
267 Map.InsertNode(P, InsertPos);
268 }
269
270 return P->getValue();
271}
272
Zhongxing Xu097fc982008-10-17 05:57:07 +0000273const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
274 return &getPersistentSValWithData(X, 0).first;
Ted Kremenekbb7a3d92008-09-18 23:09:54 +0000275}
276
277