blob: 18fdbdfaaa57cb48ad229b5f8062c5943e278d98 [file] [log] [blame]
Ted Kremenek240f1f02008-03-07 20:13:31 +00001//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- C++ -*-//
Ted Kremenekd70d0b02008-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 Kremenek240f1f02008-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 Kremenekd70d0b02008-02-16 01:12:31 +000013//
14//===----------------------------------------------------------------------===//
15
Ted Kremenek240f1f02008-03-07 20:13:31 +000016#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
Zhongxing Xu22ab7a42008-10-21 05:41:03 +000017#include "clang/Analysis/PathSensitive/SVals.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000018
19using namespace clang;
20
Zhongxing Xu6764b722008-10-30 04:58:00 +000021CompoundValData::CompoundValData(QualType t, const SVal* vals, unsigned n,
22 llvm::BumpPtrAllocator& A)
23 : T(t), NumVals(n) {
24
25 Vals = (SVal*) A.Allocate<SVal>(n);
26
27 new (Vals) SVal[n];
28
29 for (unsigned i = 0; i < n; ++i)
30 Vals[i] = vals[i];
31}
32
33void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
34 unsigned N, const SVal* Vals) {
35 T.Profile(ID);
36 ID.AddInteger(N);
37 for (unsigned i = 0; i < N; ++i)
38 Vals[i].Profile(ID);
39}
40
Zhongxing Xu1c96b242008-10-17 05:57:07 +000041typedef std::pair<SVal, uintptr_t> SValData;
42typedef std::pair<SVal, SVal> SValPair;
Ted Kremenek4d0348b2008-04-29 23:24:44 +000043
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000044
45namespace llvm {
Zhongxing Xu1c96b242008-10-17 05:57:07 +000046template<> struct FoldingSetTrait<SValData> {
47 static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000048 X.first.Profile(ID);
Ted Kremenek718c4f72008-04-29 22:17:41 +000049 ID.AddPointer( (void*) X.second);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000050 }
51};
Ted Kremenek4d0348b2008-04-29 23:24:44 +000052
Zhongxing Xu1c96b242008-10-17 05:57:07 +000053template<> struct FoldingSetTrait<SValPair> {
54 static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenek4d0348b2008-04-29 23:24:44 +000055 X.first.Profile(ID);
56 X.second.Profile(ID);
57 }
58};
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000059}
60
Zhongxing Xu1c96b242008-10-17 05:57:07 +000061typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
62 PersistentSValsTy;
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000063
Zhongxing Xu1c96b242008-10-17 05:57:07 +000064typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
65 PersistentSValPairsTy;
Ted Kremenek4d0348b2008-04-29 23:24:44 +000066
Ted Kremenek240f1f02008-03-07 20:13:31 +000067BasicValueFactory::~BasicValueFactory() {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000068 // Note that the dstor for the contents of APSIntSet will never be called,
69 // so we iterate over the set and invoke the dstor for each APSInt. This
70 // frees an aux. memory allocated to represent very large constants.
71 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
72 I->getValue().~APSInt();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000073
Zhongxing Xu1c96b242008-10-17 05:57:07 +000074 delete (PersistentSValsTy*) PersistentSVals;
75 delete (PersistentSValPairsTy*) PersistentSValPairs;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000076}
77
Ted Kremenek240f1f02008-03-07 20:13:31 +000078const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000079 llvm::FoldingSetNodeID ID;
80 void* InsertPos;
81 typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
82
83 X.Profile(ID);
84 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
85
86 if (!P) {
87 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
88 new (P) FoldNodeTy(X);
89 APSIntSet.InsertNode(P, InsertPos);
90 }
91
92 return *P;
93}
94
Ted Kremenek240f1f02008-03-07 20:13:31 +000095const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
Ted Kremenekd70d0b02008-02-16 01:12:31 +000096 bool isUnsigned) {
97 llvm::APSInt V(BitWidth, isUnsigned);
98 V = X;
99 return getValue(V);
100}
101
Ted Kremenek240f1f02008-03-07 20:13:31 +0000102const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000103
Chris Lattner98be4942008-03-05 18:54:05 +0000104 unsigned bits = Ctx.getTypeSize(T);
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000105 llvm::APSInt V(bits, T->isUnsignedIntegerType());
106 V = X;
107 return getValue(V);
108}
109
110const SymIntConstraint&
Ted Kremenek240f1f02008-03-07 20:13:31 +0000111BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000112 const llvm::APSInt& V) {
113
114 llvm::FoldingSetNodeID ID;
115 SymIntConstraint::Profile(ID, sym, Op, V);
116 void* InsertPos;
117
118 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
119
120 if (!C) {
121 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
122 new (C) SymIntConstraint(sym, Op, V);
123 SymIntCSet.InsertNode(C, InsertPos);
124 }
125
126 return *C;
127}
128
Zhongxing Xu6764b722008-10-30 04:58:00 +0000129const CompoundValData*
130BasicValueFactory::getCompoundValData(QualType T, const SVal* Vals,
131 unsigned NumVals) {
132 llvm::FoldingSetNodeID ID;
133 CompoundValData::Profile(ID, T, NumVals, Vals);
134 void* InsertPos;
135
136 CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
137
138 if (!D) {
139 D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
140 new (D) CompoundValData(T, Vals, NumVals, BPAlloc);
141 CompoundValDataSet.InsertNode(D, InsertPos);
142 }
143
144 return D;
145}
146
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000147const llvm::APSInt*
Ted Kremenek240f1f02008-03-07 20:13:31 +0000148BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000149 const llvm::APSInt& V1, const llvm::APSInt& V2) {
150
151 switch (Op) {
152 default:
153 assert (false && "Invalid Opcode.");
154
155 case BinaryOperator::Mul:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000156 return &getValue( V1 * V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000157
158 case BinaryOperator::Div:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000159 return &getValue( V1 / V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000160
161 case BinaryOperator::Rem:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000162 return &getValue( V1 % V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000163
164 case BinaryOperator::Add:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000165 return &getValue( V1 + V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000166
167 case BinaryOperator::Sub:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000168 return &getValue( V1 - V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000169
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000170 case BinaryOperator::Shl: {
171
172 // FIXME: This logic should probably go higher up, where we can
173 // test these conditions symbolically.
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000174
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000175 // FIXME: Expand these checks to include all undefined behavior.
176
177 if (V2.isSigned() && V2.isNegative())
178 return NULL;
179
180 uint64_t Amt = V2.getZExtValue();
181
182 if (Amt > V1.getBitWidth())
183 return NULL;
184
185 return &getValue( V1.operator<<( (unsigned) Amt ));
186 }
187
188 case BinaryOperator::Shr: {
189
190 // FIXME: This logic should probably go higher up, where we can
191 // test these conditions symbolically.
192
193 // FIXME: Expand these checks to include all undefined behavior.
194
195 if (V2.isSigned() && V2.isNegative())
196 return NULL;
197
198 uint64_t Amt = V2.getZExtValue();
199
200 if (Amt > V1.getBitWidth())
201 return NULL;
202
203 return &getValue( V1.operator>>( (unsigned) Amt ));
204 }
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000205
206 case BinaryOperator::LT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000207 return &getTruthValue( V1 < V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000208
209 case BinaryOperator::GT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000210 return &getTruthValue( V1 > V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000211
212 case BinaryOperator::LE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000213 return &getTruthValue( V1 <= V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000214
215 case BinaryOperator::GE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000216 return &getTruthValue( V1 >= V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000217
218 case BinaryOperator::EQ:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000219 return &getTruthValue( V1 == V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000220
221 case BinaryOperator::NE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000222 return &getTruthValue( V1 != V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000223
224 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
225
226 case BinaryOperator::And:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000227 return &getValue( V1 & V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000228
229 case BinaryOperator::Or:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000230 return &getValue( V1 | V2 );
Ted Kremenek1caf26a2008-02-19 20:53:37 +0000231
232 case BinaryOperator::Xor:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000233 return &getValue( V1 ^ V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000234 }
235}
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000236
237
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000238const std::pair<SVal, uintptr_t>&
239BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000240
241 // Lazily create the folding set.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000242 if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000243
244 llvm::FoldingSetNodeID ID;
245 void* InsertPos;
246 V.Profile(ID);
Ted Kremenek718c4f72008-04-29 22:17:41 +0000247 ID.AddPointer((void*) Data);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000248
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000249 PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000250
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000251 typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000252 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
253
254 if (!P) {
255 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
Ted Kremenek718c4f72008-04-29 22:17:41 +0000256 new (P) FoldNodeTy(std::make_pair(V, Data));
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000257 Map.InsertNode(P, InsertPos);
258 }
259
Ted Kremenek718c4f72008-04-29 22:17:41 +0000260 return P->getValue();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000261}
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000262
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000263const std::pair<SVal, SVal>&
264BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000265
266 // Lazily create the folding set.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000267 if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000268
269 llvm::FoldingSetNodeID ID;
270 void* InsertPos;
271 V1.Profile(ID);
272 V2.Profile(ID);
273
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000274 PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000275
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000276 typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000277 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
278
279 if (!P) {
280 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
281 new (P) FoldNodeTy(std::make_pair(V1, V2));
282 Map.InsertNode(P, InsertPos);
283 }
284
285 return P->getValue();
286}
287
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000288const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
289 return &getPersistentSValWithData(X, 0).first;
Ted Kremenek7360fda2008-09-18 23:09:54 +0000290}
291
292