summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp32
1 files changed, 13 insertions, 19 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
index 536de5d0376..4613ae76141 100644
--- a/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
@@ -27,6 +27,7 @@ using namespace ento;
namespace {
+/// Configuration class for Z3
class Z3Config {
friend class Z3Context;
@@ -45,17 +46,21 @@ public:
~Z3Config() { Z3_del_config(Config); }
}; // end class Z3Config
+// Function used to report errors
void Z3ErrorHandler(Z3_context Context, Z3_error_code Error) {
llvm::report_fatal_error("Z3 error: " +
llvm::Twine(Z3_get_error_msg_ex(Context, Error)));
}
+/// Wrapper for Z3 context
class Z3Context : public SMTContext {
public:
Z3_context Context;
Z3Context() : SMTContext() {
Context = Z3_mk_context_rc(Z3Config().Config);
+ // The error function is set here because the context is the first object
+ // created by the backend
Z3_set_error_handler(Context, Z3ErrorHandler);
}
@@ -65,6 +70,7 @@ public:
}
}; // end class Z3Context
+/// Wrapper for Z3 Sort
class Z3Sort : public SMTSort {
friend class Z3Solver;
@@ -73,6 +79,7 @@ class Z3Sort : public SMTSort {
Z3_sort Sort;
public:
+ /// Default constructor, mainly used by make_shared
Z3Sort(Z3Context &C, Z3_sort ZS) : SMTSort(), Context(C), Sort(ZS) {
Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
}
@@ -637,23 +644,23 @@ public:
toZ3Expr(*T).AST, toZ3Expr(*F).AST)));
}
- SMTExprRef mkSignExt(unsigned i, const SMTExprRef &Exp) override {
+ SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) override {
return newExprRef(Z3Expr(
Context, Z3_mk_sign_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
}
- SMTExprRef mkZeroExt(unsigned i, const SMTExprRef &Exp) override {
+ SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) override {
return newExprRef(Z3Expr(
Context, Z3_mk_zero_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
}
- SMTExprRef mkExtract(unsigned High, unsigned Low,
- const SMTExprRef &Exp) override {
+ SMTExprRef mkBVExtract(unsigned High, unsigned Low,
+ const SMTExprRef &Exp) override {
return newExprRef(Z3Expr(Context, Z3_mk_extract(Context.Context, High, Low,
toZ3Expr(*Exp).AST)));
}
- SMTExprRef mkConcat(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
+ SMTExprRef mkBVConcat(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
return newExprRef(
Z3Expr(Context, Z3_mk_concat(Context.Context, toZ3Expr(*LHS).AST,
toZ3Expr(*RHS).AST)));
@@ -737,27 +744,23 @@ public:
return Z3_get_bool_value(Context.Context, toZ3Expr(*Exp).AST) == Z3_L_TRUE;
}
- // Return an appropriate floating-point rounding mode.
SMTExprRef getFloatRoundingMode() override {
// TODO: Don't assume nearest ties to even rounding mode
return newExprRef(Z3Expr(Context, Z3_mk_fpa_rne(Context.Context)));
}
- /// Construct a Z3Expr from a SymbolData, given a Z3_context.
SMTExprRef fromData(const SymbolID ID, const QualType &Ty,
uint64_t BitWidth) override {
llvm::Twine Name = "$" + llvm::Twine(ID);
return mkSymbol(Name.str().c_str(), mkSort(Ty, BitWidth));
}
- /// Construct a Z3Expr from a boolean, given a Z3_context.
SMTExprRef fromBoolean(const bool Bool) override {
Z3_ast AST =
Bool ? Z3_mk_true(Context.Context) : Z3_mk_false(Context.Context);
return newExprRef(Z3Expr(Context, AST));
}
- /// Construct a Z3Expr from a finite APFloat, given a Z3_context.
SMTExprRef fromAPFloat(const llvm::APFloat &Float) override {
SMTSortRef Sort =
getFloatSort(llvm::APFloat::semanticsSizeInBits(Float.getSemantics()));
@@ -769,7 +772,6 @@ public:
toZ3Sort(*Sort).Sort)));
}
- /// Construct a Z3Expr from an APSInt, given a Z3_context.
SMTExprRef fromAPSInt(const llvm::APSInt &Int) override {
SMTSortRef Sort = getBitvectorSort(Int.getBitWidth());
Z3_ast AST = Z3_mk_numeral(Context.Context, Int.toString(10).c_str(),
@@ -777,7 +779,6 @@ public:
return newExprRef(Z3Expr(Context, AST));
}
- /// Construct a Z3Expr from an integer, given a Z3_context.
SMTExprRef fromInt(const char *Int, uint64_t BitWidth) override {
SMTSortRef Sort = getBitvectorSort(BitWidth);
Z3_ast AST = Z3_mk_numeral(Context.Context, Int, toZ3Sort(*Sort).Sort);
@@ -823,7 +824,7 @@ public:
Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), Value[0]),
Int.isUnsigned());
} else if (Sort->getBitvectorSortSize() == 128) {
- SMTExprRef ASTHigh = mkExtract(127, 64, AST);
+ 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),
@@ -849,8 +850,6 @@ public:
llvm_unreachable("Unsupported sort to integer!");
}
- /// Given an expression and a model, extract the value of this operand in
- /// the model.
bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) override {
Z3Model Model = getModel();
Z3_func_decl Func = Z3_get_app_decl(
@@ -865,8 +864,6 @@ public:
return toAPSInt(Sort, Assign, Int, true);
}
- /// Given an expression and a model, extract the value of this operand in
- /// the model.
bool getInterpretation(const SMTExprRef &Exp, llvm::APFloat &Float) override {
Z3Model Model = getModel();
Z3_func_decl Func = Z3_get_app_decl(
@@ -881,7 +878,6 @@ public:
return toAPFloat(Sort, Assign, Float, true);
}
- /// Check if the constraints are satisfiable
ConditionTruthVal check() const override {
Z3_lbool res = Z3_solver_check(Context.Context, Solver);
if (res == Z3_L_TRUE)
@@ -893,10 +889,8 @@ public:
return ConditionTruthVal();
}
- /// Push the current solver state
void push() override { return Z3_solver_push(Context.Context, Solver); }
- /// Pop the previous solver state
void pop(unsigned NumStates = 1) override {
assert(Z3_solver_get_num_scopes(Context.Context, Solver) >= NumStates);
return Z3_solver_pop(Context.Context, Solver, NumStates);
OpenPOWER on IntegriCloud