Static Value-Flow Analysis
Z3Expr.cpp
Go to the documentation of this file.
1 //===- Z3Expr.h -- Z3 conditions----------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 /*
23  * Z3Expr.h
24  *
25  * Created on: April 29, 2022
26  * Author: Xiao
27  */
28 
29 #include "Util/Z3Expr.h"
30 #include "Util/Options.h"
31 
32 namespace SVF
33 {
34 
35 z3::context *Z3Expr::ctx = nullptr;
36 z3::solver* Z3Expr::solver = nullptr;
37 
38 
41 {
42  if(solver)
43  releaseSolver();
44  delete ctx;
45  ctx = nullptr;
46 }
47 
50 {
51  delete solver;
52  solver = nullptr;
53 }
54 
56 z3::solver &Z3Expr::getSolver()
57 {
58  if (solver == nullptr)
59  {
60  solver = new z3::solver(getContext());
61  }
62  return *solver;
63 }
64 
66 z3::context &Z3Expr::getContext()
67 {
68  if (ctx == nullptr)
69  {
70  ctx = new z3::context();
71  }
72  return *ctx;
73 }
74 
77 {
78  u32_t res = 1;
79  if (z3Expr.getExpr().num_args() == 0)
80  {
81  return 1;
82  }
83  for (u32_t i = 0; i < z3Expr.getExpr().num_args(); ++i)
84  {
85  Z3Expr expr = z3Expr.getExpr().arg(i);
86  res += getExprSize(expr);
87  }
88  return res;
89 }
90 
92 Z3Expr Z3Expr::AND(const Z3Expr &lhs, const Z3Expr &rhs)
93 {
94  if (eq(lhs, Z3Expr::getFalseCond()) || eq(rhs, Z3Expr::getFalseCond()))
95  {
96  return Z3Expr::getFalseCond();
97  }
98  else if (eq(lhs, Z3Expr::getTrueCond()))
99  {
100  return rhs;
101  }
102  else if (eq(rhs, Z3Expr::getTrueCond()))
103  {
104  return lhs;
105  }
106  else
107  {
108  Z3Expr expr = (lhs && rhs).simplify();
109  // check subexpression size and option limit
111  {
112  getSolver().push();
113  getSolver().add(expr.getExpr());
114  z3::check_result res = getSolver().check();
115  getSolver().pop();
116  if (res != z3::unsat)
117  {
118  return lhs;
119  }
120  else
121  {
122  return Z3Expr::getFalseCond();
123  }
124  }
125  return expr;
126  }
127 }
128 
130 Z3Expr Z3Expr::OR(const Z3Expr &lhs, const Z3Expr &rhs)
131 {
132  if (eq(lhs, Z3Expr::getTrueCond()) || eq(rhs, Z3Expr::getTrueCond()))
133  {
134  return Z3Expr::getTrueCond();
135  }
136  else if (eq(lhs, Z3Expr::getFalseCond()))
137  {
138  return rhs;
139  }
140  else if (eq(rhs, Z3Expr::getFalseCond()))
141  {
142  return lhs;
143  }
144  else
145  {
146  Z3Expr expr = (lhs || rhs).simplify();
147  // check subexpression size and option limit
149  {
150  getSolver().push();
151  getSolver().add(expr.getExpr());
152  z3::check_result res = getSolver().check();
153  getSolver().pop();
154  if (res != z3::unsat)
155  {
156  return Z3Expr::getTrueCond();
157  }
158  else
159  {
160  return Z3Expr::getFalseCond();
161  }
162  }
163  return expr;
164  }
165 }
166 
169 {
170  std::ostringstream out;
171  out << z3Expr.getExpr();
172  return out.str();
173 }
174 }
175 
const char *const string
Definition: cJSON.h:172
static const Option< u32_t > MaxZ3Size
Definition: Options.h:193
static z3::solver & getSolver()
Get z3 solver, singleton design here to make sure we only have one context.
Definition: Z3Expr.cpp:56
static z3::solver * solver
Definition: Z3Expr.h:42
static Z3Expr AND(const Z3Expr &lhs, const Z3Expr &rhs)
compute AND, used for branch condition
Definition: Z3Expr.cpp:92
static std::string dumpStr(const Z3Expr &z3Expr)
output Z3 expression as a string
Definition: Z3Expr.cpp:168
const z3::expr & getExpr() const
Definition: Z3Expr.h:86
static u32_t getExprSize(const Z3Expr &z3Expr)
get the number of subexpression of a Z3 expression
Definition: Z3Expr.cpp:76
static void releaseSolver()
release z3 solver
Definition: Z3Expr.cpp:49
static void releaseContext()
release z3 context
Definition: Z3Expr.cpp:40
static Z3Expr getTrueCond()
Return the unique true condition.
Definition: Z3Expr.h:288
static Z3Expr OR(const Z3Expr &lhs, const Z3Expr &rhs)
compute OR, used for branch condition
Definition: Z3Expr.cpp:130
friend bool eq(const Z3Expr &lhs, const Z3Expr &rhs)
Definition: Z3Expr.h:269
static z3::context & getContext()
Get z3 context, singleton design here to make sure we only have one context.
Definition: Z3Expr.cpp:66
static z3::context * ctx
Definition: Z3Expr.h:41
static Z3Expr getFalseCond()
Return the unique false condition.
Definition: Z3Expr.h:295
Z3Expr simplify() const
Definition: Z3Expr.h:137
for isBitcode
Definition: BasicTypes.h:68
unsigned u32_t
Definition: GeneralType.h:46