summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
diff options
context:
space:
mode:
authorMikhail R. Gadelha <mikhail.ramalho@gmail.com>2018-07-26 11:17:13 +0000
committerMikhail R. Gadelha <mikhail.ramalho@gmail.com>2018-07-26 11:17:13 +0000
commit127093129aa049f05594c80f7f4ae09187bb94a8 (patch)
treea14a1ca19898b2bd4522b0a86809c88e2468fb27 /clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
parent4a612d4bf290346ec018a74fd245c8e30ff93de7 (diff)
downloadbcm5719-llvm-127093129aa049f05594c80f7f4ae09187bb94a8.tar.gz
bcm5719-llvm-127093129aa049f05594c80f7f4ae09187bb94a8.zip
[analyzer] Fixed method to get APSInt model
Summary: This patch replaces the current method of getting an `APSInt` from Z3's model by calling generic API method `getBitvector` instead of `Z3_get_numeral_uint64`. By calling `getBitvector`, there's no need to handle bitvectors with bit width == 128 separately. And, as a bonus, clang now compiles correctly with Z3 4.7.1. Reviewers: NoQ, george.karpenkov Reviewed By: george.karpenkov Subscribers: xazax.hun, szepet, a.sidorin Differential Revision: https://reviews.llvm.org/D49818 llvm-svn: 338020
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp41
1 files changed, 18 insertions, 23 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
index 4613ae76141..7379ded49c8 100644
--- a/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
@@ -734,10 +734,11 @@ public:
toZ3Sort(*Sort).Sort)));
}
- const llvm::APSInt getBitvector(const SMTExprRef &Exp) override {
- // FIXME: this returns a string and the bitWidth is overridden
- return llvm::APSInt(
- Z3_get_numeral_string(Context.Context, toZ3Expr(*Exp).AST));
+ llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth,
+ bool isUnsigned) override {
+ return llvm::APSInt(llvm::APInt(
+ BitWidth, Z3_get_numeral_string(Context.Context, toZ3Expr(*Exp).AST),
+ 10));
}
bool getBoolean(const SMTExprRef &Exp) override {
@@ -814,26 +815,20 @@ public:
return false;
}
- uint64_t Value[2];
- // Force cast because Z3 defines __uint64 to be a unsigned long long
- // type, which isn't compatible with a unsigned long type, even if they
- // are the same size.
- Z3_get_numeral_uint64(Context.Context, toZ3Expr(*AST).AST,
- reinterpret_cast<__uint64 *>(&Value[0]));
- if (Sort->getBitvectorSortSize() <= 64) {
- Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), Value[0]),
- Int.isUnsigned());
- } else if (Sort->getBitvectorSortSize() == 128) {
- SMTExprRef ASTHigh = mkBVExtract(127, 64, AST);
- Z3_get_numeral_uint64(Context.Context, toZ3Expr(*AST).AST,
- reinterpret_cast<__uint64 *>(&Value[1]));
- Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), Value),
- Int.isUnsigned());
- } else {
- assert(false && "Bitwidth not supported!");
- return false;
+ // FIXME: This function is also used to retrieve floating-point values,
+ // which can be 16, 32, 64 or 128 bits long. Bitvectors can be anything
+ // between 1 and 64 bits long, which is the reason we have this weird
+ // guard. In the future, we need proper calls in the backend to retrieve
+ // floating-points and its special values (NaN, +/-infinity, +/-zero),
+ // then we can drop this weird condition.
+ if (Sort->getBitvectorSortSize() <= 64 ||
+ Sort->getBitvectorSortSize() == 128) {
+ Int = getBitvector(AST, Int.getBitWidth(), Int.isUnsigned());
+ return true;
}
- return true;
+
+ assert(false && "Bitwidth not supported!");
+ return false;
}
if (Sort->isBooleanSort()) {
OpenPOWER on IntegriCloud