12
12
#include " clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
13
13
#include " clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h"
14
14
#include " clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h"
15
+ #include " clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h"
15
16
#include " clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h"
16
17
17
18
#include " clang/Config/config.h"
@@ -162,40 +163,25 @@ class Z3Sort : public SMTSort {
162
163
}
163
164
}; // end class Z3Sort
164
165
165
- class Z3Expr {
166
- friend class Z3Model ;
166
+ class Z3Expr : public SMTExpr {
167
167
friend class Z3Solver ;
168
168
169
169
Z3Context &Context;
170
170
171
171
Z3_ast AST;
172
172
173
- Z3Expr (Z3Context &C, Z3_ast ZA) : Context(C), AST(ZA) {
174
- assert (C.Context != nullptr );
173
+ Z3Expr (Z3Context &C, Z3_ast ZA) : SMTExpr(), Context(C), AST(ZA) {
175
174
Z3_inc_ref (Context.Context , AST);
176
175
}
177
176
178
- // Determine whether two float semantics are equivalent
179
- static bool areEquivalent (const llvm::fltSemantics &LHS,
180
- const llvm::fltSemantics &RHS) {
181
- return (llvm::APFloat::semanticsPrecision (LHS) ==
182
- llvm::APFloat::semanticsPrecision (RHS)) &&
183
- (llvm::APFloat::semanticsMinExponent (LHS) ==
184
- llvm::APFloat::semanticsMinExponent (RHS)) &&
185
- (llvm::APFloat::semanticsMaxExponent (LHS) ==
186
- llvm::APFloat::semanticsMaxExponent (RHS)) &&
187
- (llvm::APFloat::semanticsSizeInBits (LHS) ==
188
- llvm::APFloat::semanticsSizeInBits (RHS));
189
- }
190
-
191
177
public:
192
178
// / Override implicit copy constructor for correct reference counting.
193
- Z3Expr (const Z3Expr &Copy) : Context(Copy.Context), AST(Copy.AST) {
179
+ Z3Expr (const Z3Expr &Copy) : SMTExpr(), Context(Copy.Context), AST(Copy.AST) {
194
180
Z3_inc_ref (Context.Context , AST);
195
181
}
196
182
197
183
// / Provide move constructor
198
- Z3Expr (Z3Expr &&Move) : Context(Move.Context), AST(nullptr ) {
184
+ Z3Expr (Z3Expr &&Move) : SMTExpr(), Context(Move.Context), AST(nullptr ) {
199
185
*this = std::move (Move);
200
186
}
201
187
@@ -215,40 +201,18 @@ class Z3Expr {
215
201
Z3_dec_ref (Context.Context , AST);
216
202
}
217
203
218
- // / Get the corresponding IEEE floating-point type for a given bitwidth.
219
- static const llvm::fltSemantics &getFloatSemantics (unsigned BitWidth) {
220
- switch (BitWidth) {
221
- default :
222
- llvm_unreachable (" Unsupported floating-point semantics!" );
223
- break ;
224
- case 16 :
225
- return llvm::APFloat::IEEEhalf ();
226
- case 32 :
227
- return llvm::APFloat::IEEEsingle ();
228
- case 64 :
229
- return llvm::APFloat::IEEEdouble ();
230
- case 128 :
231
- return llvm::APFloat::IEEEquad ();
232
- }
233
- }
234
-
235
- void Profile (llvm::FoldingSetNodeID &ID) const {
204
+ void Profile (llvm::FoldingSetNodeID &ID) const override {
236
205
ID.AddInteger (Z3_get_ast_hash (Context.Context , AST));
237
206
}
238
207
239
- bool operator <(const Z3Expr &Other) const {
240
- llvm::FoldingSetNodeID ID1, ID2;
241
- Profile (ID1);
242
- Other.Profile (ID2);
243
- return ID1 < ID2;
244
- }
245
-
246
208
// / Comparison of AST equality, not model equivalence.
247
- bool operator ==( const Z3Expr &Other) const {
209
+ bool equal_to (SMTExpr const &Other) const override {
248
210
assert (Z3_is_eq_sort (Context.Context , Z3_get_sort (Context.Context , AST),
249
- Z3_get_sort (Context.Context , Other.AST )) &&
211
+ Z3_get_sort (Context.Context ,
212
+ static_cast <const Z3Expr &>(Other).AST )) &&
250
213
" AST's must have the same sort" );
251
- return Z3_is_eq_ast (Context.Context , AST, Other.AST );
214
+ return Z3_is_eq_ast (Context.Context , AST,
215
+ static_cast <const Z3Expr &>(Other).AST );
252
216
}
253
217
254
218
// / Override implicit move constructor for correct reference counting.
@@ -259,11 +223,9 @@ class Z3Expr {
259
223
return *this ;
260
224
}
261
225
262
- void print (raw_ostream &OS) const {
226
+ void print (raw_ostream &OS) const override {
263
227
OS << Z3_ast_to_string (Context.Context , AST);
264
228
}
265
-
266
- LLVM_DUMP_METHOD void dump () const { print (llvm::errs ()); }
267
229
}; // end class Z3Expr
268
230
269
231
class Z3Model {
@@ -312,6 +274,36 @@ class Z3Model {
312
274
LLVM_DUMP_METHOD void dump () const { print (llvm::errs ()); }
313
275
}; // end class Z3Model
314
276
277
+ // / Get the corresponding IEEE floating-point type for a given bitwidth.
278
+ static const llvm::fltSemantics &getFloatSemantics (unsigned BitWidth) {
279
+ switch (BitWidth) {
280
+ default :
281
+ llvm_unreachable (" Unsupported floating-point semantics!" );
282
+ break ;
283
+ case 16 :
284
+ return llvm::APFloat::IEEEhalf ();
285
+ case 32 :
286
+ return llvm::APFloat::IEEEsingle ();
287
+ case 64 :
288
+ return llvm::APFloat::IEEEdouble ();
289
+ case 128 :
290
+ return llvm::APFloat::IEEEquad ();
291
+ }
292
+ }
293
+
294
+ // Determine whether two float semantics are equivalent
295
+ static bool areEquivalent (const llvm::fltSemantics &LHS,
296
+ const llvm::fltSemantics &RHS) {
297
+ return (llvm::APFloat::semanticsPrecision (LHS) ==
298
+ llvm::APFloat::semanticsPrecision (RHS)) &&
299
+ (llvm::APFloat::semanticsMinExponent (LHS) ==
300
+ llvm::APFloat::semanticsMinExponent (RHS)) &&
301
+ (llvm::APFloat::semanticsMaxExponent (LHS) ==
302
+ llvm::APFloat::semanticsMaxExponent (RHS)) &&
303
+ (llvm::APFloat::semanticsSizeInBits (LHS) ==
304
+ llvm::APFloat::semanticsSizeInBits (RHS));
305
+ }
306
+
315
307
class Z3Solver {
316
308
friend class Z3ConstraintManager ;
317
309
@@ -812,14 +804,13 @@ class Z3Solver {
812
804
813
805
llvm::APSInt Int (Sort.getFloatSortSize (), true );
814
806
const llvm::fltSemantics &Semantics =
815
- Z3Expr:: getFloatSemantics (Sort.getFloatSortSize ());
807
+ getFloatSemantics (Sort.getFloatSortSize ());
816
808
Z3Sort BVSort = getBitvectorSort (Sort.getFloatSortSize ());
817
809
if (!toAPSInt (BVSort, AST, Int, true )) {
818
810
return false ;
819
811
}
820
812
821
- if (useSemantics &&
822
- !Z3Expr::areEquivalent (Float.getSemantics (), Semantics)) {
813
+ if (useSemantics && !areEquivalent (Float.getSemantics (), Semantics)) {
823
814
assert (false && " Floating-point types don't match!" );
824
815
return false ;
825
816
}
0 commit comments