void goto_symext::symex_free(const expr2tc &expr) { const code_free2t &code = to_code_free2t(expr); // Trigger 'free'-mode dereference of this pointer. Should generate various // dereference failure callbacks. expr2tc tmp = code.operand; dereference(tmp, dereferencet::FREE); // Don't rely on the output of dereference in free mode; instead fetch all // the internal dereference state for pointed at objects, and creates claims // that if pointed at, their offset is zero. internal_deref_items.clear(); tmp = code.operand; // Create temporary, dummy, dereference tmp = dereference2tc(get_uint8_type(), tmp); dereference(tmp, dereferencet::INTERNAL); // Only add assertions to check pointer offset if pointer check is enabled if(!options.get_bool_option("no-pointer-check")) { for(auto const &item : internal_deref_items) { guardt g = cur_state->guard; g.add(item.guard); expr2tc offset = item.offset; expr2tc eq = equality2tc(offset, gen_ulong(0)); g.guard_expr(eq); claim(eq, "Operand of free must have zero pointer offset"); } } // Clear the alloc bit, and set the deallocated bit. type2tc sym_type = type2tc(new array_type2t(get_bool_type(), expr2tc(), true)); expr2tc ptr_obj = pointer_object2tc(pointer_type2(), code.operand); dereference(ptr_obj, dereferencet::READ); symbol2tc dealloc_sym(sym_type, deallocd_arr_name); index2tc dealloc_index_expr(get_bool_type(), dealloc_sym, ptr_obj); expr2tc truth = gen_true_expr(); symex_assign(code_assign2tc(dealloc_index_expr, truth), true); symbol2tc valid_sym(sym_type, valid_ptr_arr_name); index2tc valid_index_expr(get_bool_type(), valid_sym, ptr_obj); expr2tc falsity = gen_false_expr(); symex_assign(code_assign2tc(valid_index_expr, falsity), true); }
void goto_symext::symex_free(const expr2tc &expr) { const code_free2t &code = to_code_free2t(expr); // Trigger 'free'-mode dereference of this pointer. Should generate various // dereference failure callbacks. expr2tc tmp = code.operand; dereference(tmp, false, true); // Don't rely on the output of dereference in free mode; instead fetch all // the internal dereference state for pointed at objects, and creates claims // that if pointed at, their offset is zero. internal_deref_items.clear(); tmp = code.operand; // Create temporary, dummy, dereference tmp = dereference2tc(get_uint8_type(), tmp); dereference(tmp, false, false, true); // 'internal' dereference for (const auto &item : internal_deref_items) { guardt g = cur_state->guard; g.add(item.guard); expr2tc offset = item.offset; expr2tc eq = equality2tc(offset, zero_ulong); g.guard_expr(eq); claim(eq, "Operand of free must have zero pointer offset"); } // Clear the alloc bit, and set the deallocated bit. guardt guard; type2tc sym_type = type2tc(new array_type2t(get_bool_type(), expr2tc(), true)); pointer_object2tc ptr_obj(pointer_type2(), code.operand); symbol2tc dealloc_sym(sym_type, deallocd_arr_name); index2tc dealloc_index_expr(get_bool_type(), dealloc_sym, ptr_obj); expr2tc truth = true_expr; symex_assign_rec(dealloc_index_expr, truth, guard); symbol2tc valid_sym(sym_type, valid_ptr_arr_name); index2tc valid_index_expr(get_bool_type(), valid_sym, ptr_obj); expr2tc falsity = false_expr; symex_assign_rec(valid_index_expr, falsity, guard); }