Skip to content

Commit bca62c2

Browse files
committed
Rebase
1 parent 8c5ae1c commit bca62c2

File tree

20 files changed

+257
-13
lines changed

20 files changed

+257
-13
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,5 @@ src/test/rustdoc-gui/src/**.lock
8080
/.ninja_deps
8181
/.ninja_log
8282
/src/test/dashboard
83+
*Cargo.lock
84+
src/test/rmc-dependency-test/diamond-dependency/build

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ exclude = [
5151
"src/tools/x",
5252
# stdarch has its own Cargo workspace
5353
"library/stdarch",
54+
# dependency tests have their own workspace
55+
"src/test/rmc-dependency-test/dependency3"
5456
]
5557

5658
[profile.release.package.compiler_builtins]

compiler/rustc_codegen_llvm/src/gotoc/mir_to_goto/codegen/operand.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::gotoc::cbmc::goto_program::{Expr, Location, Stmt, Symbol, Type};
44
use crate::gotoc::mir_to_goto::utils::slice_fat_ptr;
55
use crate::gotoc::mir_to_goto::GotocCtx;
66
use rustc_ast::ast::Mutability;
7-
use rustc_hir::def_id::LOCAL_CRATE;
87
use rustc_middle::mir::interpret::{
98
read_target_uint, AllocId, Allocation, ConstValue, GlobalAlloc, Scalar,
109
};
@@ -353,9 +352,10 @@ impl<'tcx> GotocCtx<'tcx> {
353352
sym.clone().to_expr().address_of()
354353
}
355354
GlobalAlloc::Memory(alloc) => {
356-
// crate_name added so that allocations in different crates don't clash
357-
let crate_name = self.tcx.crate_name(LOCAL_CRATE);
358-
let name = format!("{}::{:?}", crate_name, alloc_id);
355+
// Full (mangled) crate name added so that allocations from different
356+
// crates do not conflict. The name alone is insufficient becase Rust
357+
// allows different versions of the same crate to be used.
358+
let name = format!("{}::{:?}", self.full_crate_name(), alloc_id);
359359
self.codegen_allocation(alloc, |_| name.clone(), Some(name.clone()))
360360
}
361361
};

compiler/rustc_codegen_llvm/src/gotoc/mir_to_goto/codegen/typ.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,21 @@ impl<'tcx> GotocCtx<'tcx> {
374374
// code. See the implementation of pretty_print_region on line 1720 in
375375
// compiler/rustc_middle/src/ty/print/pretty.rs.
376376
let name = name.replace(" + \'static", "").replace("\'static ", "");
377-
name
377+
378+
// Crate resolution: mangled names need to be distinct across different versions
379+
// of the same crate that could be pulled in by dependencies. However, RMC's
380+
// treatment of FFI C calls asssumes that we generate the same name for structs
381+
// as the C name, so don't mangle in that case.
382+
// TODO: this is likely insufficient if a dependent crate has two versions of
383+
// linked C libraries
384+
// https://github.com/model-checking/rmc/issues/450
385+
if is_repr_c_adt(t) {
386+
return name;
387+
}
388+
389+
// Add unique type id
390+
let id_u64 = self.tcx.type_id_hash(t);
391+
format!("{}::{}", name, id_u64)
378392
}
379393

380394
#[allow(dead_code)]
@@ -1201,6 +1215,14 @@ pub fn pointee_type(pointer_type: Ty<'tcx>) -> Option<Ty<'tcx>> {
12011215
}
12021216
}
12031217

1218+
/// Is the MIR type using a C representation (marked with #[repr(C)] at the source level)?
1219+
pub fn is_repr_c_adt(mir_type: Ty<'tcx>) -> bool {
1220+
match mir_type.kind() {
1221+
ty::Adt(def, _) => def.repr.c(),
1222+
_ => false,
1223+
}
1224+
}
1225+
12041226
impl<'tcx> GotocCtx<'tcx> {
12051227
/// A pointer to the mir type should be a thin pointer.
12061228
pub fn use_thin_pointer(&self, mir_type: Ty<'tcx>) -> bool {

compiler/rustc_codegen_llvm/src/gotoc/mir_to_goto/compiler_interface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl CodegenBackend for GotocCodegenBackend {
8080
MonoItem::GlobalAsm(_) => {
8181
warn!(
8282
"Crate {} contains global ASM, which is not handled by RMC",
83-
c.crate_name()
83+
c.short_crate_name()
8484
);
8585
}
8686
}

compiler/rustc_codegen_llvm/src/gotoc/mir_to_goto/context/goto_ctx.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ use crate::gotoc::cbmc::goto_program::{
2121
use crate::gotoc::cbmc::utils::aggr_name;
2222
use crate::gotoc::cbmc::{MachineModel, RoundingMode};
2323
use crate::gotoc::mir_to_goto::overrides::{type_and_fn_hooks, GotocHooks, GotocTypeHooks};
24+
use crate::gotoc::mir_to_goto::utils::full_crate_name;
2425
use rustc_data_structures::owning_ref::OwningRef;
2526
use rustc_data_structures::rustc_erase_owner;
2627
use rustc_data_structures::stable_map::FxHashMap;
2728
use rustc_data_structures::sync::MetadataRef;
28-
use rustc_hir::def_id::LOCAL_CRATE;
2929
use rustc_middle::middle::cstore::MetadataLoader;
3030
use rustc_middle::mir::interpret::Allocation;
3131
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, TyAndLayout};
@@ -43,6 +43,8 @@ pub struct GotocCtx<'tcx> {
4343
pub symbol_table: SymbolTable,
4444
pub hooks: GotocHooks<'tcx>,
4545
pub type_hooks: GotocTypeHooks<'tcx>,
46+
/// the full crate name, including versioning info
47+
pub full_crate_name: String,
4648
/// a global counter for generating unique names for global variables
4749
pub global_var_count: u64,
4850
/// map a global allocation to a name in the symbol table
@@ -61,6 +63,7 @@ impl<'tcx> GotocCtx<'tcx> {
6163
symbol_table,
6264
hooks: fhks,
6365
type_hooks: thks,
66+
full_crate_name: full_crate_name(tcx),
6467
global_var_count: 0,
6568
alloc_map: FxHashMap::default(),
6669
current_fn: None,
@@ -70,10 +73,6 @@ impl<'tcx> GotocCtx<'tcx> {
7073

7174
/// Getters
7275
impl<'tcx> GotocCtx<'tcx> {
73-
pub fn crate_name(&self) -> String {
74-
self.tcx.crate_name(LOCAL_CRATE).to_string()
75-
}
76-
7776
pub fn current_fn(&self) -> &CurrentFnCtx<'tcx> {
7877
self.current_fn.as_ref().unwrap()
7978
}
@@ -225,7 +224,7 @@ impl<'tcx> GotocCtx<'tcx> {
225224
pub fn next_global_name(&mut self) -> String {
226225
let c = self.global_var_count;
227226
self.global_var_count += 1;
228-
format!("{}::global::{}::", self.tcx.crate_name(LOCAL_CRATE), c)
227+
format!("{}::global::{}::", self.full_crate_name(), c)
229228
}
230229
}
231230

compiler/rustc_codegen_llvm/src/gotoc/mir_to_goto/utils/names.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@
55
66
use crate::gotoc::mir_to_goto::GotocCtx;
77
use rustc_hir::def_id::DefId;
8+
use rustc_hir::def_id::LOCAL_CRATE;
89
use rustc_hir::definitions::DefPathDataName;
10+
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
911
use rustc_middle::mir::Local;
1012
use rustc_middle::ty::print::with_no_trimmed_paths;
1113
use rustc_middle::ty::{self, Instance, TyCtxt};
1214
use tracing::debug;
1315

1416
impl<'tcx> GotocCtx<'tcx> {
17+
/// The short crate name without versioning information.
18+
pub fn short_crate_name(&self) -> String {
19+
self.tcx.crate_name(LOCAL_CRATE).to_string()
20+
}
21+
22+
/// The full crate name including versioning info
23+
pub fn full_crate_name(&self) -> &str {
24+
&self.full_crate_name
25+
}
26+
1527
pub fn codegen_var_base_name(&self, l: &Local) -> String {
1628
match self.find_debug_info(l) {
1729
None => format!("var_{}", l.index()),
@@ -98,6 +110,21 @@ impl<'tcx> GotocCtx<'tcx> {
98110
}
99111
}
100112

113+
/// The full crate name should use the Codegen Unit builder to include full name resolution,
114+
/// for example, the versioning information if a build requires two different versions
115+
/// of the same crate.
116+
pub fn full_crate_name(tcx: TyCtxt<'tcx>) -> String {
117+
format!(
118+
"{}::{}",
119+
CodegenUnitNameBuilder::new(tcx).build_cgu_name(
120+
LOCAL_CRATE,
121+
&[] as &[String; 0],
122+
None as Option<String>
123+
),
124+
tcx.crate_name(LOCAL_CRATE)
125+
)
126+
}
127+
101128
//TODO: These were moved from hooks.rs, where they didn't have a goto context. Normalize them.
102129
pub fn sig_of_instance<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::FnSig<'tcx> {
103130
let ty = instance.ty(tcx, ty::ParamEnv::reveal_all());

scripts/rmc-regression.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
# SPDX-License-Identifier: Apache-2.0 OR MIT
44

@@ -30,3 +30,13 @@ $SCRIPT_DIR/std-lib-regression.sh
3030

3131
# Check codegen of firecracker
3232
$SCRIPT_DIR/codegen-firecracker.sh
33+
34+
# Check that we can use RMC on crates with a diamond dependency graph,
35+
# with two different versions of the same crate.
36+
#
37+
# dependency1
38+
# / \ v0.1.0
39+
# main dependency3
40+
# \ / v0.1.1
41+
# dependency2
42+
./src/test/rmc-dependency-test/diamond-dependency/run-dependency-test.sh
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
[package]
5+
name = "dependency3"
6+
version = "0.1.0"
7+
edition = "2018"
8+
9+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10+
11+
[dependencies]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
pub struct Foo {
5+
x: i32,
6+
}
7+
8+
// Export a function that takes a struct type which differs between this crate
9+
// and the other vesion
10+
pub fn take_foo(foo: &Foo) -> i32 {
11+
foo.x
12+
}
13+
14+
pub fn give_foo() -> Foo {
15+
Foo { x: 1 }
16+
}
17+
18+
pub fn get_int() -> i32 {
19+
// Use a constant to force an MIR GlobalAllocation::Memory.
20+
// Use a non-i32 so there will be a conflict between this
21+
// version and the other version. The constant is also a
22+
// different value than the other version of this dependency.
23+
let one = &(1 as i8);
24+
return *one as i32
25+
}

0 commit comments

Comments
 (0)