blob: 72ad0a5ed8f1d3fabcfd6943ce9854eba2650af3 [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"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000017
18using namespace clang;
19
Zhongxing Xu6764b722008-10-30 04:58:00 +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
Zhongxing Xu1c96b242008-10-17 05:57:07 +000026typedef std::pair<SVal, uintptr_t> SValData;
27typedef std::pair<SVal, SVal> SValPair;
Ted Kremenek4d0348b2008-04-29 23:24:44 +000028
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000029namespace llvm {
Zhongxing Xu1c96b242008-10-17 05:57:07 +000030template<> struct FoldingSetTrait<SValData> {
31 static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000032 X.first.Profile(ID);
Ted Kremenek718c4f72008-04-29 22:17:41 +000033 ID.AddPointer( (void*) X.second);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000034 }
35};
Ted Kremenek4d0348b2008-04-29 23:24:44 +000036
Zhongxing Xu1c96b242008-10-17 05:57:07 +000037template<> struct FoldingSetTrait<SValPair> {
38 static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
Ted Kremenek4d0348b2008-04-29 23:24:44 +000039 X.first.Profile(ID);
40 X.second.Profile(ID);
41 }
42};
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000043}
44
Zhongxing Xu1c96b242008-10-17 05:57:07 +000045typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
46 PersistentSValsTy;
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000047
Zhongxing Xu1c96b242008-10-17 05:57:07 +000048typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
49 PersistentSValPairsTy;
Ted Kremenek4d0348b2008-04-29 23:24:44 +000050
Ted Kremenek240f1f02008-03-07 20:13:31 +000051BasicValueFactory::~BasicValueFactory() {
Ted Kremenekd70d0b02008-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 Kremenek0fe33bc2008-04-22 21:10:18 +000057
Zhongxing Xu1c96b242008-10-17 05:57:07 +000058 delete (PersistentSValsTy*) PersistentSVals;
59 delete (PersistentSValPairsTy*) PersistentSValPairs;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000060}
61
Ted Kremenek240f1f02008-03-07 20:13:31 +000062const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
Ted Kremenekd70d0b02008-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
Zhongxing Xue8a964b2008-11-22 13:21:46 +000079const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
80 bool isUnsigned) {
81 llvm::APSInt V(X, isUnsigned);
82 return getValue(V);
83}
84
Ted Kremenek240f1f02008-03-07 20:13:31 +000085const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
Ted Kremenekd70d0b02008-02-16 01:12:31 +000086 bool isUnsigned) {
87 llvm::APSInt V(BitWidth, isUnsigned);
88 V = X;
89 return getValue(V);
90}
91
Ted Kremenek240f1f02008-03-07 20:13:31 +000092const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000093
Chris Lattner98be4942008-03-05 18:54:05 +000094 unsigned bits = Ctx.getTypeSize(T);
Ted Kremenekfa6228d2009-03-11 02:52:39 +000095 llvm::APSInt V(bits, T->isUnsignedIntegerType() || Loc::IsLocType(T));
Ted Kremenekd70d0b02008-02-16 01:12:31 +000096 V = X;
97 return getValue(V);
98}
99
Zhongxing Xu6764b722008-10-30 04:58:00 +0000100const CompoundValData*
Ted Kremenek632e8b82008-10-30 17:44:46 +0000101BasicValueFactory::getCompoundValData(QualType T,
102 llvm::ImmutableList<SVal> Vals) {
103
Zhongxing Xu6764b722008-10-30 04:58:00 +0000104 llvm::FoldingSetNodeID ID;
Ted Kremenek632e8b82008-10-30 17:44:46 +0000105 CompoundValData::Profile(ID, T, Vals);
Zhongxing Xu6764b722008-10-30 04:58:00 +0000106 void* InsertPos;
107
108 CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
109
110 if (!D) {
111 D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
Ted Kremenek632e8b82008-10-30 17:44:46 +0000112 new (D) CompoundValData(T, Vals);
Zhongxing Xu6764b722008-10-30 04:58:00 +0000113 CompoundValDataSet.InsertNode(D, InsertPos);
114 }
115
116 return D;
117}
118
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000119const llvm::APSInt*
Ted Kremenek240f1f02008-03-07 20:13:31 +0000120BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000121 const llvm::APSInt& V1, const llvm::APSInt& V2) {
122
123 switch (Op) {
124 default:
125 assert (false && "Invalid Opcode.");
126
127 case BinaryOperator::Mul:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000128 return &getValue( V1 * V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000129
130 case BinaryOperator::Div:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000131 return &getValue( V1 / V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000132
133 case BinaryOperator::Rem:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000134 return &getValue( V1 % V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000135
136 case BinaryOperator::Add:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000137 return &getValue( V1 + V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000138
139 case BinaryOperator::Sub:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000140 return &getValue( V1 - V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000141
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000142 case BinaryOperator::Shl: {
143
144 // FIXME: This logic should probably go higher up, where we can
145 // test these conditions symbolically.
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000146
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000147 // FIXME: Expand these checks to include all undefined behavior.
148
149 if (V2.isSigned() && V2.isNegative())
150 return NULL;
151
152 uint64_t Amt = V2.getZExtValue();
153
154 if (Amt > V1.getBitWidth())
155 return NULL;
156
157 return &getValue( V1.operator<<( (unsigned) Amt ));
158 }
159
160 case BinaryOperator::Shr: {
161
162 // FIXME: This logic should probably go higher up, where we can
163 // test these conditions symbolically.
164
165 // FIXME: Expand these checks to include all undefined behavior.
166
167 if (V2.isSigned() && V2.isNegative())
168 return NULL;
169
170 uint64_t Amt = V2.getZExtValue();
171
172 if (Amt > V1.getBitWidth())
173 return NULL;
174
175 return &getValue( V1.operator>>( (unsigned) Amt ));
176 }
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000177
178 case BinaryOperator::LT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000179 return &getTruthValue( V1 < V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000180
181 case BinaryOperator::GT:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000182 return &getTruthValue( V1 > V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000183
184 case BinaryOperator::LE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000185 return &getTruthValue( V1 <= V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000186
187 case BinaryOperator::GE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000188 return &getTruthValue( V1 >= V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000189
190 case BinaryOperator::EQ:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000191 return &getTruthValue( V1 == V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000192
193 case BinaryOperator::NE:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000194 return &getTruthValue( V1 != V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000195
196 // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
197
198 case BinaryOperator::And:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000199 return &getValue( V1 & V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000200
201 case BinaryOperator::Or:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000202 return &getValue( V1 | V2 );
Ted Kremenek1caf26a2008-02-19 20:53:37 +0000203
204 case BinaryOperator::Xor:
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000205 return &getValue( V1 ^ V2 );
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000206 }
207}
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000208
209
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000210const std::pair<SVal, uintptr_t>&
211BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000212
213 // Lazily create the folding set.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000214 if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000215
216 llvm::FoldingSetNodeID ID;
217 void* InsertPos;
218 V.Profile(ID);
Ted Kremenek718c4f72008-04-29 22:17:41 +0000219 ID.AddPointer((void*) Data);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000220
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000221 PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000222
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000223 typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000224 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
225
226 if (!P) {
227 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
Ted Kremenek718c4f72008-04-29 22:17:41 +0000228 new (P) FoldNodeTy(std::make_pair(V, Data));
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000229 Map.InsertNode(P, InsertPos);
230 }
231
Ted Kremenek718c4f72008-04-29 22:17:41 +0000232 return P->getValue();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +0000233}
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000234
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000235const std::pair<SVal, SVal>&
236BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000237
238 // Lazily create the folding set.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000239 if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000240
241 llvm::FoldingSetNodeID ID;
242 void* InsertPos;
243 V1.Profile(ID);
244 V2.Profile(ID);
245
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000246 PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000247
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000248 typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
Ted Kremenek4d0348b2008-04-29 23:24:44 +0000249 FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
250
251 if (!P) {
252 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
253 new (P) FoldNodeTy(std::make_pair(V1, V2));
254 Map.InsertNode(P, InsertPos);
255 }
256
257 return P->getValue();
258}
259
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000260const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
261 return &getPersistentSValWithData(X, 0).first;
Ted Kremenek7360fda2008-09-18 23:09:54 +0000262}
263
264