Skip to content

Commit

Permalink
Produce more pretty names (rust-lang#1310)
Browse files Browse the repository at this point in the history
  • Loading branch information
fzaiser authored Jul 13, 2022
1 parent 13f7a98 commit e282561
Show file tree
Hide file tree
Showing 21 changed files with 175 additions and 110 deletions.
39 changes: 23 additions & 16 deletions cprover_bindings/src/goto_program/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,20 @@ impl Symbol {

/// The symbol that defines the type of the struct or union.
/// For a struct foo this is the symbol "tag-foo" that maps to the type struct foo.
pub fn aggr_ty<T: Into<InternedString>>(t: Type, pretty_name: Option<T>) -> Symbol {
pub fn aggr_ty<T: Into<InternedString>>(t: Type, pretty_name: T) -> Symbol {
//TODO take location
let pretty_name = pretty_name.intern();
let pretty_name = pretty_name.into();
let base_name = t.tag().unwrap();
let name = aggr_tag(base_name);
Symbol::new(name, Location::none(), t, SymbolValues::None, Some(base_name), pretty_name)
.with_is_type(true)
Symbol::new(
name,
Location::none(),
t,
SymbolValues::None,
Some(base_name),
Some(pretty_name),
)
.with_is_type(true)
}

pub fn builtin_function<T: Into<InternedString>>(
Expand All @@ -123,7 +130,7 @@ impl Symbol {
name,
Type::code_with_unnamed_parameters(param_types, return_type),
None,
None::<InternedString>,
name,
Location::builtin_function(name, None),
)
}
Expand All @@ -150,18 +157,18 @@ impl Symbol {
name: T,
typ: Type,
body: Option<Stmt>,
pretty_name: Option<U>,
pretty_name: U,
loc: Location,
) -> Symbol {
let name = name.into();
let pretty_name = pretty_name.intern();
let pretty_name = pretty_name.into();
Symbol::new(
name.to_string(),
loc,
typ,
body.map_or(SymbolValues::None, SymbolValues::Stmt),
Some(name),
pretty_name,
Some(pretty_name),
)
.with_is_lvalue(true)
}
Expand Down Expand Up @@ -209,7 +216,7 @@ impl Symbol {

pub fn struct_type<T: Into<InternedString>>(
name: T,
pretty_name: Option<InternedString>,
pretty_name: InternedString,
components: Vec<DatatypeComponent>,
) -> Symbol {
let name = name.into();
Expand All @@ -218,35 +225,35 @@ impl Symbol {

pub fn union_type<T: Into<InternedString>, U: Into<InternedString>>(
name: T,
pretty_name: Option<U>,
pretty_name: U,
components: Vec<DatatypeComponent>,
) -> Symbol {
let name = name.into();
let pretty_name = pretty_name.intern();
let pretty_name = pretty_name.into();
Symbol::aggr_ty(Type::union_type(name, components), pretty_name)
}

pub fn empty_struct(name: InternedString, pretty_name: Option<InternedString>) -> Symbol {
pub fn empty_struct(name: InternedString, pretty_name: InternedString) -> Symbol {
Symbol::aggr_ty(Type::empty_struct(name), pretty_name)
}

pub fn empty_union(name: InternedString, pretty_name: Option<InternedString>) -> Symbol {
pub fn empty_union(name: InternedString, pretty_name: InternedString) -> Symbol {
Symbol::aggr_ty(Type::empty_union(name), pretty_name)
}

pub fn incomplete_struct<T: Into<InternedString>, U: Into<InternedString>>(
name: T,
pretty_name: Option<U>,
pretty_name: U,
) -> Symbol {
Symbol::aggr_ty(Type::incomplete_struct(name), pretty_name)
}

pub fn incomplete_union<T: Into<InternedString>, U: Into<InternedString>>(
name: T,
pretty_name: Option<U>,
pretty_name: U,
) -> Symbol {
let name = name.into();
let pretty_name = pretty_name.intern();
let pretty_name = pretty_name.into();
Symbol::aggr_ty(Type::incomplete_union(name), pretty_name)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ impl Transformer for ExprTransformer {
"main",
Type::code(Vec::new(), Type::CInteger(CIntType::Int)),
Some(Stmt::block(main_body, Location::none())),
Some("main"),
"main",
Location::none(),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl Transformer for NondetTransformer {

// Add function to symbol table
let func_sym =
Symbol::function(&identifier, typ, Some(body), Some(&identifier), Location::none());
Symbol::function(&identifier, typ, Some(body), &identifier, Location::none());
self.mut_symbol_table().insert(func_sym);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ mod tests {

let struct_type = Symbol::struct_type(
"s",
None,
"s".into(),
vec![
DatatypeComponent::field("a", Type::float()),
DatatypeComponent::padding("b", 4),
Expand Down Expand Up @@ -283,7 +283,7 @@ mod tests {

let union_type = Symbol::union_type(
"u",
crate::NO_PRETTY_NAME,
"u",
vec![
DatatypeComponent::field("a", Type::float()),
DatatypeComponent::field("c", Type::double()),
Expand Down Expand Up @@ -330,7 +330,7 @@ mod tests {
&name,
Type::code_with_unnamed_parameters(vec![], Type::empty()),
Some(body),
crate::NO_PRETTY_NAME,
&name,
Location::none(),
));
curr_var += 1;
Expand Down
3 changes: 0 additions & 3 deletions cprover_bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,3 @@ pub use irep::serialize;
pub use machine_model::{MachineModel, RoundingMode};
mod cbmc_string;
pub use cbmc_string::{InternString, InternStringOption, InternedString};

// Rust has difficulty resolving types for None option values: this gives rustc a hint.
pub const NO_PRETTY_NAME: Option<InternedString> = None;
9 changes: 7 additions & 2 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use kani_metadata::HarnessMetadata;
use rustc_ast::ast;
use rustc_ast::{Attribute, LitKind};
use rustc_middle::mir::{HasLocalDecls, Local};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, Instance};
use std::collections::BTreeMap;
use std::convert::TryInto;
Expand All @@ -20,7 +21,11 @@ use tracing::{debug, info_span};
/// Utility to skip functions that can't currently be successfully codgenned.
impl<'tcx> GotocCtx<'tcx> {
fn should_skip_current_fn(&self) -> bool {
match self.current_fn().readable_name() {
let current_fn_name =
with_no_trimmed_paths!(self.tcx.def_path_str(self.current_fn().instance().def_id()));
// We cannot use self.current_fn().readable_name() because it gives the monomorphized type, which is more difficult to match on.
// Ideally we should not rely on the pretty-printed name here. Tracked here: https://github.com/model-checking/kani/issues/1374
match current_fn_name.as_str() {
// https://github.com/model-checking/kani/issues/202
"fmt::ArgumentV1::<'a>::as_usize" => true,
// https://github.com/model-checking/kani/issues/282
Expand Down Expand Up @@ -233,7 +238,7 @@ impl<'tcx> GotocCtx<'tcx> {
fname,
ctx.fn_typ(),
None,
Some(ctx.current_fn().readable_name()),
ctx.current_fn().readable_name(),
ctx.codegen_span(&mir.span),
)
});
Expand Down
39 changes: 19 additions & 20 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::codegen_cprover_gotoc::utils::slice_fat_ptr;
use crate::codegen_cprover_gotoc::GotocCtx;
use crate::unwrap_or_return_codegen_unimplemented;
use cbmc::goto_program::{DatatypeComponent, Expr, Location, Stmt, Symbol, Type};
use cbmc::NO_PRETTY_NAME;
use rustc_ast::ast::Mutability;
use rustc_middle::mir::interpret::{
read_target_uint, AllocId, Allocation, ConstValue, GlobalAlloc, Scalar,
Expand Down Expand Up @@ -317,6 +316,7 @@ impl<'tcx> GotocCtx<'tcx> {

fn codegen_direct_literal(&mut self, ty: Ty<'tcx>, init: Expr) -> Expr {
let func_name = format!("gen-{}:direct", self.ty_mangled_name(ty));
let pretty_name = format!("init_direct::<{}>", self.ty_pretty_name(ty));
let cgt = self.codegen_ty(ty);
self.ensure(&func_name, |tcx, _| {
let target_ty = init.typ().clone(); // N
Expand All @@ -333,7 +333,7 @@ impl<'tcx> GotocCtx<'tcx> {
&func_name,
Type::code(vec![param.to_function_parameter()], cgt),
Some(Stmt::block(body, Location::none())),
NO_PRETTY_NAME,
pretty_name,
Location::none(),
)
});
Expand Down Expand Up @@ -500,28 +500,26 @@ impl<'tcx> GotocCtx<'tcx> {
/// Codegen alloc as a static global variable with initial value
fn codegen_alloc_in_memory(&mut self, alloc: &'tcx Allocation, name: String) {
debug!("codegen_alloc_in_memory name: {}", name);
let struct_name = &format!("{}::struct", name);

// The declaration of a static variable may have one type and the constant initializer for
// a static variable may have a different type. This is because Rust uses bit patterns for
// initializers. For example, for a boolean static variable, the variable will have type
// CBool and the initializer will be a single byte (a one-character array) representing the
// bit pattern for the boolean value.
let alloc_typ_ref =
self.ensure_struct(&format!("{}::struct", name), NO_PRETTY_NAME, |ctx, _| {
ctx.codegen_allocation_data(alloc)
.iter()
.enumerate()
.map(|(i, d)| match d {
AllocData::Bytes(bytes) => DatatypeComponent::field(
&i.to_string(),
Type::unsigned_int(8).array_of(bytes.len()),
),
AllocData::Expr(e) => {
DatatypeComponent::field(&i.to_string(), e.typ().clone())
}
})
.collect()
});
let alloc_typ_ref = self.ensure_struct(&struct_name, &struct_name, |ctx, _| {
ctx.codegen_allocation_data(alloc)
.iter()
.enumerate()
.map(|(i, d)| match d {
AllocData::Bytes(bytes) => DatatypeComponent::field(
&i.to_string(),
Type::unsigned_int(8).array_of(bytes.len()),
),
AllocData::Expr(e) => DatatypeComponent::field(&i.to_string(), e.typ().clone()),
})
.collect()
});

// The global static variable may not be in the symbol table if we are dealing
// with a literal that can be statically allocated.
Expand Down Expand Up @@ -606,6 +604,7 @@ impl<'tcx> GotocCtx<'tcx> {
fn codegen_niche_literal(&mut self, ty: Ty<'tcx>, offset: usize, init: Expr) -> Expr {
let cgt = self.codegen_ty(ty);
let fname = self.codegen_niche_init_name(ty);
let pretty_name = format!("init_niche<{}>", self.ty_pretty_name(ty));
self.ensure(&fname, |tcx, _| {
let target_ty = init.typ().clone(); // N
let param = tcx.gen_function_local_variable(1, &fname, target_ty.clone());
Expand All @@ -620,7 +619,7 @@ impl<'tcx> GotocCtx<'tcx> {
&fname,
Type::code(vec![param.to_function_parameter()], cgt),
Some(Stmt::block(body, Location::none())),
NO_PRETTY_NAME,
pretty_name,
Location::none(),
)
});
Expand All @@ -642,7 +641,7 @@ impl<'tcx> GotocCtx<'tcx> {
&func,
funct.clone(),
None,
Some(ctx.readable_instance_name(instance)),
ctx.readable_instance_name(instance),
Location::none(),
)
.with_is_extern(true)
Expand Down
10 changes: 6 additions & 4 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::unwrap_or_return_codegen_unimplemented;
use cbmc::goto_program::{Expr, Location, Stmt, Symbol, Type};
use cbmc::utils::BUG_REPORT_URL;
use cbmc::MachineModel;
use cbmc::NO_PRETTY_NAME;
use cbmc::{btree_string_map, InternString, InternedString};
use num::bigint::BigInt;
use rustc_middle::mir::{AggregateKind, BinOp, CastKind, NullOp, Operand, Place, Rvalue, UnOp};
Expand Down Expand Up @@ -211,6 +210,7 @@ impl<'tcx> GotocCtx<'tcx> {
res_ty: Ty<'tcx>,
) -> Expr {
let func_name = format!("gen-repeat<{}>", self.ty_mangled_name(res_ty));
let pretty_name = format!("init_array_repeat<{}>", self.ty_pretty_name(res_ty));
self.ensure(&func_name, |tcx, _| {
let paramt = tcx.codegen_ty(tcx.operand_ty(op));
let res_t = tcx.codegen_ty(res_ty);
Expand Down Expand Up @@ -241,7 +241,7 @@ impl<'tcx> GotocCtx<'tcx> {
&func_name,
Type::code(vec![inp.to_function_parameter()], res_t),
Some(Stmt::block(body, Location::none())),
NO_PRETTY_NAME,
&pretty_name,
Location::none(),
)
});
Expand Down Expand Up @@ -851,7 +851,9 @@ impl<'tcx> GotocCtx<'tcx> {
// We skip an entire submodule of the standard library, so drop is missing
// for it. Build and insert a function that just calls an unimplemented block
// to maintain soundness.
let drop_sym_name = format!("{}_unimplemented", self.symbol_name(drop_instance));
let drop_sym_name = format!("drop_unimplemented_{}", self.symbol_name(drop_instance));
let pretty_name =
format!("drop_unimplemented<{}>", self.readable_instance_name(drop_instance));
let drop_sym = self.ensure(&drop_sym_name, |ctx, name| {
// Function body
let unimplemented = ctx
Expand All @@ -878,7 +880,7 @@ impl<'tcx> GotocCtx<'tcx> {
name,
Type::code(vec![param_sym.to_function_parameter()], Type::empty()),
Some(Stmt::block(vec![unimplemented], Location::none())),
NO_PRETTY_NAME,
pretty_name,
Location::none(),
)
});
Expand Down
Loading

0 comments on commit e282561

Please sign in to comment.