Skip to content

Commit

Permalink
Fix #83045 by moving some crate loading verification code to a better…
Browse files Browse the repository at this point in the history
… place.
  • Loading branch information
michaelwoerister committed Mar 26, 2021
1 parent bba4088 commit 09bab38
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
11 changes: 8 additions & 3 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,16 +350,13 @@ impl<'a> CrateLoader<'a> {
let Library { source, metadata } = lib;
let crate_root = metadata.get_root();
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
self.verify_no_symbol_conflicts(&crate_root)?;

let private_dep =
self.sess.opts.externs.get(&name.as_str()).map_or(false, |e| e.is_private_dep);

// Claim this crate number and cache it
let cnum = self.cstore.alloc_new_crate_num();

self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?;

info!(
"register crate `{}` (cnum = {}. private_dep = {})",
crate_root.name(),
Expand Down Expand Up @@ -394,6 +391,14 @@ impl<'a> CrateLoader<'a> {
None
};

// Perform some verification *after* resolve_crate_deps() above is
// known to have been successful. It seems that - in error cases - the
// cstore can be in a temporarily invalid state between cnum allocation
// and dependency resolution and the verification code would produce
// ICEs in that case (see #83045).
self.verify_no_symbol_conflicts(&crate_root)?;
self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?;

let crate_metadata = CrateMetadata::new(
self.sess,
metadata,
Expand Down
33 changes: 33 additions & 0 deletions src/test/run-make-fulldeps/issue-83045/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
include ../../run-make-fulldeps/tools.mk

# This test case creates a situation where the crate loader would run
# into an ICE when confronted with an invalid setup where it cannot
# find the dependency of a direct dependency.
#
# The test case makes sure that the compiler produces the expected
# error message but does not ICE immediately after.
#
# See https://github.com/rust-lang/rust/issues/83045

# This is a platform-independent issue, no need to waste time testing
# everywhere.
# only-x86_64
# only-linux

# NOTE: We use BARE_RUSTC below so that the compiler can't find liba.rlib
# If we used RUSTC the additional '-L TMPDIR' option would allow rustc to
# actually find the crate.
#
# We check that we get the expected error message
# But that we do not get an ICE

all:
$(RUSTC) --crate-name=a --crate-type=rlib a.rs --verbose
$(RUSTC) --crate-name=b --crate-type=rlib --extern a=$(TMPDIR)/liba.rlib b.rs --verbose
$(BARE_RUSTC) --out-dir $(TMPDIR) \
--extern b=$(TMPDIR)/libb.rlib \
--crate-type=rlib \
--edition=2018 \
c.rs 2>&1 | tee $(TMPDIR)/output.txt || exit 0
$(CGREP) E0463 < $(TMPDIR)/output.txt
$(CGREP) -v "internal compiler error" < $(TMPDIR)/output.txt
1 change: 1 addition & 0 deletions src/test/run-make-fulldeps/issue-83045/a.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty on purpose
1 change: 1 addition & 0 deletions src/test/run-make-fulldeps/issue-83045/b.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern crate a;
1 change: 1 addition & 0 deletions src/test/run-make-fulldeps/issue-83045/c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use b as _;

0 comments on commit 09bab38

Please sign in to comment.