def select(self, ctx, return_type, cond, cond_type, trueval, trueval_type, falseval, falseval_type): self.assertion(ctx, not cond.is_poison(), "path condition is poison") assert itypes.integer_size(cond_type) == 1 assert return_type == trueval_type assert trueval_type == falseval_type return util.If(cond, trueval, falseval)
def sext(self, ctx, return_type, a, atype, **kwargs): outsize = itypes.integer_size(return_type) insize = itypes.integer_size(atype) assert outsize > insize if z3.is_bool(a): return util.If(a, z3.BitVecVal(1, outsize), z3.BitVecVal(0, outsize)) return z3.SignExt(outsize - insize, a)
def ashr(self, ctx, return_type, a, atype, b, btype, nuw=False, nsw=False): assert atype == return_type assert atype == btype assert not nuw and not nsw return util.partial_eval( ctx, util.If(z3.ULT(b, z3.BitVecVal(btype.size(), btype.size())), a >> b, self.get_poison(btype)))
def test_pointer_pointer_pointer(self): ctx = newctx() a = dt.fresh_ptr(ctx, util.fresh_name( 'a'), it.PointerType(it.PointerType(it.IntType(64)))) b = dt.fresh_ptr(ctx, util.fresh_name( 'b'), it.PointerType(it.IntType(64))) c = dt.fresh_ptr(ctx, util.fresh_name( 'c'), it.PointerType(it.IntType(64))) cond = z3.Bool('cond') p = util.If(cond, b, c) a.write(ctx, p) print a.read(ctx).read(ctx)
def test_pointer_ite(self): ctx = newctx() p1 = dt.fresh_ptr(ctx, util.fresh_name( 'p'), it.PointerType(it.IntType(64))) p2 = dt.fresh_ptr(ctx, util.fresh_name( 'p'), it.PointerType(it.IntType(64))) cond = z3.Bool('cond') p3 = util.If(cond, p1, p2) p3.write(ctx, util.i64(4)) s = z3.Solver() s.add(z3.Not(z3.Implies(cond, p1.read(ctx) == util.i64(4)))) self.assertEquals(s.check(), z3.unsat) s = z3.Solver() s.add(z3.Not(z3.Implies(z3.Not(cond), p2.read(ctx) == util.i64(4)))) self.assertEquals(s.check(), z3.unsat)
def inner_read(self, ctx): return util.If(cond, p1.read(ctx), p2.read(ctx))
def inner_write(self, ctx, value): p1.write(ctx, util.If(cond, value, p1.read(ctx))) p2.write(ctx, util.If(z3.Not(cond), value, p2.read(ctx)))
raise false_branch_exc return falseval ctx.merge(scond, true_ctx, false_ctx) if true_branch_exc is not None: raise true_branch_exc elif false_branch_exc is not None: raise false_branch_exc if trueval is None: assert falseval is None, "Neither or both should be None: {!r} v {!r}".format( trueval, falseval) return else: return util.If(cond, trueval, falseval) def switch(self, ctx, value, value_type, default_case, *cases): if not cases: return default_case() case_value, case_value_type, case_branch = cases[0] cases = cases[1:] assert value_type == case_value_type def rest(): return self.switch(ctx, value, value_type, default_case, *cases) return self.branch(ctx, value == case_value, itypes.IntType(1), case_branch, rest)