Skip to content

Commit 93049ca

Browse files
markrtuttleMark R. Tuttle
authored andcommitted
Complete and replace the unsized pointer cast implementation (rust-lang#88)
* Complete and replace the unsized pointer cast implementation * Respond to code review of unsized pointer cast implementation Co-authored-by: Mark R. Tuttle <mrtuttle@amazon.com>
1 parent 84496da commit 93049ca

File tree

6 files changed

+379
-108
lines changed

6 files changed

+379
-108
lines changed

compiler/rustc_codegen_llvm/src/gotoc/cbmc/goto_program/expr.rs

+41
Original file line numberDiff line numberDiff line change
@@ -1205,3 +1205,44 @@ impl Expr {
12051205
SwitchCase::new(self, body)
12061206
}
12071207
}
1208+
1209+
impl Expr {
1210+
/// Given a struct value (Expr), construct a mapping from struct field names
1211+
/// (Strings) to struct field values (Exprs).
1212+
///
1213+
/// The Struct variant of the Expr enum models the fields of a struct as a
1214+
/// list of pairs (data type components) consisting of a field name and a
1215+
/// field value. A pair may represent an actual field in the struct or just
1216+
/// padding in the layout of the struct. This function returns a mapping of
1217+
/// field names (ignoring the padding fields) to field values. The result
1218+
/// is suitable for use in the struct_expr constructor. This makes it
1219+
/// easier to look up or modify field values of a struct.
1220+
pub fn struct_field_exprs(&self, symbol_table: &SymbolTable) -> BTreeMap<String, Expr> {
1221+
let struct_type = self.typ();
1222+
assert!(struct_type.is_struct_tag());
1223+
1224+
let mut exprs: BTreeMap<String, Expr> = BTreeMap::new();
1225+
let fields = symbol_table.lookup_fields_in_type(struct_type).unwrap();
1226+
match self.struct_expr_values() {
1227+
Some(values) => {
1228+
assert!(fields.len() == values.len());
1229+
for i in 0..fields.len() {
1230+
if fields[i].is_padding() {
1231+
continue;
1232+
}
1233+
exprs.insert(fields[i].name().to_string(), values[i].clone());
1234+
}
1235+
}
1236+
None => {
1237+
for i in 0..fields.len() {
1238+
if fields[i].is_padding() {
1239+
continue;
1240+
}
1241+
let name = fields[i].name();
1242+
exprs.insert(name.to_string(), self.clone().member(name, &symbol_table));
1243+
}
1244+
}
1245+
}
1246+
exprs
1247+
}
1248+
}

compiler/rustc_codegen_llvm/src/gotoc/cbmc/goto_program/typ.rs

+28
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use self::Type::*;
55
use super::super::utils::aggr_name;
66
use super::super::MachineModel;
77
use super::{Expr, SymbolTable};
8+
use std::collections::BTreeMap;
89
use std::convert::TryInto;
910
use std::fmt::Debug;
1011

@@ -782,3 +783,30 @@ impl Type {
782783
}
783784
}
784785
}
786+
787+
impl Type {
788+
/// Given a struct type, construct a mapping from struct field names
789+
/// (Strings) to struct field types (Types).
790+
///
791+
/// The Struct variant of the Type enum models the fields of a struct as a
792+
/// list of pairs (data type components) consisting of a field name and a
793+
/// field type. A pair may represent an actual field in the struct or just
794+
/// padding in the layout of the struct. This function returns a mapping of
795+
/// field names (ignoring the padding fields) to field types. This makes it
796+
/// easier to look up field types (and modestly easier to interate over
797+
/// field types).
798+
pub fn struct_field_types(&self, symbol_table: &SymbolTable) -> BTreeMap<String, Type> {
799+
// TODO: Accept a Struct type, too, and not just a StructTag assumed below.
800+
assert!(self.is_struct_tag());
801+
802+
let mut types: BTreeMap<String, Type> = BTreeMap::new();
803+
let fields = symbol_table.lookup_fields_in_type(self).unwrap();
804+
for field in fields {
805+
if field.is_padding() {
806+
continue;
807+
}
808+
types.insert(field.name().to_string(), field.typ());
809+
}
810+
types
811+
}
812+
}

compiler/rustc_codegen_llvm/src/gotoc/place.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl<'tcx> ProjectedPlace<'tcx> {
6363

6464
/// Constructor
6565
impl<'tcx> ProjectedPlace<'tcx> {
66-
fn check_expr_typ(expr: &Expr, typ: &TypeOrVariant<'tcx>, ctx: &mut GotocCtx<'tcx>) -> bool {
66+
fn _check_expr_typ(expr: &Expr, typ: &TypeOrVariant<'tcx>, ctx: &mut GotocCtx<'tcx>) -> bool {
6767
match typ {
6868
TypeOrVariant::Type(t) => &ctx.codegen_ty(t) == expr.typ(),
6969
TypeOrVariant::Variant(_) => true, //TODO, what to do here?

0 commit comments

Comments
 (0)