blob: b33c277f86f90c9d68fba9db0798e2c671938b7b [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
Mike Stump1eb44332009-09-09 15:08:12 +000011// of APSInt objects and symbolic constraints used by GRExprEngine
Ted Kremenek240f1f02008-03-07 20:13:31 +000012// 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"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000017
18using namespace clang;
19
Mike Stump1eb44332009-09-09 15:08:12 +000020void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
Ted Kremenek632e8b82008-10-30 17:44:46 +000021 llvm::ImmutableList<SVal> L) {
Zhongxing Xu6764b722008-10-30 04:58:00 +000022 T.Profile(ID);
Ted Kremenek632e8b82008-10-30 17:44:46 +000023 ID.AddPointer(L.getInternalPointer());
Zhongxing Xu6764b722008-10-30 04:58:00 +000024}
25
Ted Kremeneka5e81f12009-08-06 01:20:57 +000026void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
27 const GRState *state,
28 const TypedRegion *region) {
29 ID.AddPointer(state);
30 ID.AddPointer(region);
31}
32
Zhongxing Xu1c96b242008-10-17 05:57:07 +000033typedef std::pair<SVal, uintptr_t> SValData;
34typedef std::pair<SVal, SVal> SValPair;
Ted Kremenek4d0348b2008-04-29 23:24:44 +000035
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000036namespace llvm {
Zhongxing Xu1c96b242008-10-17 05:57:07 +000037template<> struct FoldingSetTrait<SValData> {
38 static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000039 X.first.Profile(ID);
Ted Kremenek718c4f72008-04-29 22:17:41 +000040 ID.AddPointer( (void*) X.second);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000041 }
42};
Mike Stump1eb44332009-09-09 15:08:12 +000043
Zhongxing Xu1c96b242008-10-17 05:57:07 +000044template<> struct FoldingSetTrait<SValPair> {
45 static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenek4d0348b2008-04-29 23:24:44 +000046 X.first.Profile(ID);
47 X.second.Profile(ID);
48 }
49};
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000050}
51
Zhongxing Xu1c96b242008-10-17 05:57:07 +000052typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
53 PersistentSValsTy;
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000054
Zhongxing Xu1c96b242008-10-17 05:57:07 +000055typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
56 PersistentSValPairsTy;
Ted Kremenek4d0348b2008-04-29 23:24:44 +000057
Ted Kremenek240f1f02008-03-07 20:13:31 +000058BasicValueFactory::~BasicValueFactory() {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000059 // Note that the dstor for the contents of APSIntSet will never be called,
60 // so we iterate over the set and invoke the dstor for each APSInt. This
61 // frees an aux. memory allocated to represent very large constants.
62 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
63 I->getValue().~APSInt();
Mike Stump1eb44332009-09-09 15:08:12 +000064
65 delete (PersistentSValsTy*) PersistentSVals;
Zhongxing Xu1c96b242008-10-17 05:57:07 +000066 delete (PersistentSValPairsTy*) PersistentSValPairs;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000067}
68
Ted Kremenek240f1f02008-03-07 20:13:31 +000069const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000070 llvm::FoldingSetNodeID ID;
71 void* InsertPos;
72 typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
Mike Stump1eb44332009-09-09 15:08:12 +000073
Ted Kremenekd70d0b02008-02-16 01:12:31 +000074 X.Profile(ID);
75 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
Mike Stump1eb44332009-09-09 15:08:12 +000076
77 if (!P) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000078 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
79 new (P) FoldNodeTy(X);
80 APSIntSet.InsertNode(P, InsertPos);
81 }
Mike Stump1eb44332009-09-09 15:08:12 +000082
Ted Kremenekd70d0b02008-02-16 01:12:31 +000083 return *P;
84}
85
Zhongxing Xue8a964b2008-11-22 13:21:46 +000086const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
87 bool isUnsigned) {
88 llvm::APSInt V(X, isUnsigned);
89 return getValue(V);
90}
91
Ted Kremenek240f1f02008-03-07 20:13:31 +000092const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
Ted Kremenekd70d0b02008-02-16 01:12:31 +000093 bool isUnsigned) {
94 llvm::APSInt V(BitWidth, isUnsigned);
Mike Stump1eb44332009-09-09 15:08:12 +000095 V = X;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000096 return getValue(V);
97}
98
Ted Kremenek240f1f02008-03-07 20:13:31 +000099const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
Mike Stump1eb44332009-09-09 15:08:12 +0000100
Chris Lattner98be4942008-03-05 18:54:05 +0000101 unsigned bits = Ctx.getTypeSize(T);
Ted Kremenekfa6228d2009-03-11 02:52:39 +0000102 llvm::APSInt V(bits, T->isUnsignedIntegerType() || Loc::IsLocType(T));
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000103 V = X;
104 return getValue(V);
105}
106
Mike Stump1eb44332009-09-09 15:08:12 +0000107const CompoundValData*
Ted Kremenek632e8b82008-10-30 17:44:46 +0000108BasicValueFactory::getCompoundValData(QualType T,
109 llvm::ImmutableList<SVal> Vals) {
Mike Stump1eb44332009-09-09 15:08:12 +0000110
Zhongxing Xu6764b722008-10-30 04:58:00 +0000111 llvm::FoldingSetNodeID ID;
Ted Kremenek632e8b82008-10-30 17:44:46 +0000112 CompoundValData::Profile(ID, T, Vals);
Zhongxing Xu6764b722008-10-30 04:58:00 +0000113 void* InsertPos;
114
115 CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
116
117 if (!D) {
118 D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
Ted Kremenek632e8b82008-10-30 17:44:46 +0000119 new (D) CompoundValData(T, Vals);
Zhongxing Xu6764b722008-10-30 04:58:00 +0000120 CompoundValDataSet.InsertNode(D, InsertPos);
121 }
122
123 return D;
124}
125
Ted Kremeneka5e81f12009-08-06 01:20:57 +0000126const LazyCompoundValData*
127BasicValueFactory::getLazyCompoundValData(const GRState *state,
128 const TypedRegion *region) {
129 llvm::FoldingSetNodeID ID;
130 LazyCompoundValData::Profile(ID, state, region);
131 void* InsertPos;
Mike Stump1eb44332009-09-09 15:08:12 +0000132
Ted Kremeneka5e81f12009-08-06 01:20:57 +0000133 LazyCompoundValData *D =
134 LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
Mike Stump1eb44332009-09-09 15:08:12 +0000135
Ted Kremeneka5e81f12009-08-06 01:20:57 +0000136 if (!D) {
137 D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
138 new (D) LazyCompoundValData(state, region);
139 LazyCompoundValDataSet.InsertNode(D, InsertPos);
140 }
Mike Stump1eb44332009-09-09 15:08:12 +0000141
Ted Kremeneka5e81f12009-08-06 01:20:57 +0000142 return D;
143}
144
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000145const llvm::APSInt*
Ted Kremenek240f1f02008-03-07 20:13:31 +0000146BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000147 const llvm::APSInt& V1, const llvm::APSInt& V2) {
Mike Stump1eb44332009-09-09 15:08:12 +0000148
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000149 switch (Op) {
150 default:
151 assert (false && "Invalid Opcode.");
Mike Stump1eb44332009-09-09 15:08:12 +0000152
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000153 case BinaryOperator::Mul:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000154 return &getValue( V1 * V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000155
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000156 case BinaryOperator::Div:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000157 return &getValue( V1 / V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000158
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000159 case BinaryOperator::Rem:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000160 return &getValue( V1 % V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000161
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000162 case BinaryOperator::Add:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000163 return &getValue( V1 + V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000164
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000165 case BinaryOperator::Sub:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000166 return &getValue( V1 - V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000167
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000168 case BinaryOperator::Shl: {
169
170 // FIXME: This logic should probably go higher up, where we can
171 // test these conditions symbolically.
Mike Stump1eb44332009-09-09 15:08:12 +0000172
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000173 // FIXME: Expand these checks to include all undefined behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000174
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000175 if (V2.isSigned() && V2.isNegative())
176 return NULL;
Mike Stump1eb44332009-09-09 15:08:12 +0000177
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000178 uint64_t Amt = V2.getZExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000179
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000180 if (Amt > V1.getBitWidth())
181 return NULL;
Mike Stump1eb44332009-09-09 15:08:12 +0000182
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000183 return &getValue( V1.operator<<( (unsigned) Amt ));
184 }
Mike Stump1eb44332009-09-09 15:08:12 +0000185
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000186 case BinaryOperator::Shr: {
Mike Stump1eb44332009-09-09 15:08:12 +0000187
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000188 // FIXME: This logic should probably go higher up, where we can
189 // test these conditions symbolically.
Mike Stump1eb44332009-09-09 15:08:12 +0000190
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000191 // FIXME: Expand these checks to include all undefined behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000192
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000193 if (V2.isSigned() && V2.isNegative())
194 return NULL;
Mike Stump1eb44332009-09-09 15:08:12 +0000195
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000196 uint64_t Amt = V2.getZExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000197
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000198 if (Amt > V1.getBitWidth())
199 return NULL;
Mike Stump1eb44332009-09-09 15:08:12 +0000200
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000201 return &getValue( V1.operator>>( (unsigned) Amt ));
202 }
Mike Stump1eb44332009-09-09 15:08:12 +0000203
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000204 case BinaryOperator::LT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000205 return &getTruthValue( V1 < V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000206
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000207 case BinaryOperator::GT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000208 return &getTruthValue( V1 > V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000209
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000210 case BinaryOperator::LE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000211 return &getTruthValue( V1 <= V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000212
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000213 case BinaryOperator::GE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000214 return &getTruthValue( V1 >= V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000215
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000216 case BinaryOperator::EQ:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000217 return &getTruthValue( V1 == V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000218
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000219 case BinaryOperator::NE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000220 return &getTruthValue( V1 != V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000221
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000222 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
Mike Stump1eb44332009-09-09 15:08:12 +0000223
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000224 case BinaryOperator::And:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000225 return &getValue( V1 & V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000226
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000227 case BinaryOperator::Or:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000228 return &getValue( V1 | V2 );
Mike Stump1eb44332009-09-09 15:08:12 +0000229
Ted Kremenek1caf26a2008-02-19 20:53:37 +0000230 case BinaryOperator::Xor:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000231 return &getValue( V1 ^ V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000232 }
233}
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000234
235
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000236const std::pair<SVal, uintptr_t>&
237BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
Mike Stump1eb44332009-09-09 15:08:12 +0000238
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000239 // Lazily create the folding set.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000240 if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
Mike Stump1eb44332009-09-09 15:08:12 +0000241
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000242 llvm::FoldingSetNodeID ID;
243 void* InsertPos;
244 V.Profile(ID);
Ted Kremenek718c4f72008-04-29 22:17:41 +0000245 ID.AddPointer((void*) Data);
Mike Stump1eb44332009-09-09 15:08:12 +0000246
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000247 PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
Mike Stump1eb44332009-09-09 15:08:12 +0000248
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000249 typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000250 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
Mike Stump1eb44332009-09-09 15:08:12 +0000251
252 if (!P) {
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000253 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
Ted Kremenek718c4f72008-04-29 22:17:41 +0000254 new (P) FoldNodeTy(std::make_pair(V, Data));
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000255 Map.InsertNode(P, InsertPos);
256 }
257
Ted Kremenek718c4f72008-04-29 22:17:41 +0000258 return P->getValue();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000259}
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000260
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000261const std::pair<SVal, SVal>&
262BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
Mike Stump1eb44332009-09-09 15:08:12 +0000263
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000264 // Lazily create the folding set.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000265 if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
Mike Stump1eb44332009-09-09 15:08:12 +0000266
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000267 llvm::FoldingSetNodeID ID;
268 void* InsertPos;
269 V1.Profile(ID);
270 V2.Profile(ID);
Mike Stump1eb44332009-09-09 15:08:12 +0000271
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000272 PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
Mike Stump1eb44332009-09-09 15:08:12 +0000273
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000274 typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000275 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
Mike Stump1eb44332009-09-09 15:08:12 +0000276
277 if (!P) {
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000278 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
279 new (P) FoldNodeTy(std::make_pair(V1, V2));
280 Map.InsertNode(P, InsertPos);
281 }
Mike Stump1eb44332009-09-09 15:08:12 +0000282
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000283 return P->getValue();
284}
285
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000286const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
287 return &getPersistentSValWithData(X, 0).first;
Mike Stump1eb44332009-09-09 15:08:12 +0000288}
Ted Kremenek7360fda2008-09-18 23:09:54 +0000289
290