Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[beta] backports #86225

Merged
merged 7 commits into from
Jun 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::back::write::create_informational_target_machine;
use crate::llvm;
use crate::{llvm, llvm_util};
use libc::c_int;
use rustc_codegen_ssa::target_features::supported_target_features;
use rustc_data_structures::fx::FxHashSet;
Expand Down Expand Up @@ -84,6 +84,17 @@ unsafe fn configure_llvm(sess: &Session) {
if !sess.opts.debugging_opts.no_generate_arange_section {
add("-generate-arange-section", false);
}

// FIXME(nagisa): disable the machine outliner by default in LLVM versions 11, where it was
// introduced and up.
//
// This should remain in place until https://reviews.llvm.org/D103167 is fixed. If LLVM
// has been upgraded since, consider adjusting the version check below to contain an upper
// bound.
if llvm_util::get_version() >= (11, 0, 0) {
add("-enable-machine-outliner=never", false);
}

match sess.opts.debugging_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
MergeFunctions::Aliases => {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,17 +406,17 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {

impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Span, String> {
let ctxt = SyntaxContext::decode(decoder)?;
let tag = u8::decode(decoder)?;

if tag == TAG_INVALID_SPAN {
return Ok(DUMMY_SP);
if tag == TAG_PARTIAL_SPAN {
return Ok(DUMMY_SP.with_ctxt(ctxt));
}

debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN);

let lo = BytePos::decode(decoder)?;
let len = BytePos::decode(decoder)?;
let ctxt = SyntaxContext::decode(decoder)?;
let hi = lo + len;

let sess = if let Some(sess) = decoder.sess {
Expand Down
82 changes: 41 additions & 41 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,48 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {

impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
if *self == rustc_span::DUMMY_SP {
return TAG_INVALID_SPAN.encode(s);
let span = self.data();

// Don't serialize any `SyntaxContext`s from a proc-macro crate,
// since we don't load proc-macro dependencies during serialization.
// This means that any hygiene information from macros used *within*
// a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
// definition) will be lost.
//
// This can show up in two ways:
//
// 1. Any hygiene information associated with identifier of
// a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
// Since proc-macros can only be invoked from a different crate,
// real code should never need to care about this.
//
// 2. Using `Span::def_site` or `Span::mixed_site` will not
// include any hygiene information associated with the definition
// site. This means that a proc-macro cannot emit a `$crate`
// identifier which resolves to one of its dependencies,
// which also should never come up in practice.
//
// Additionally, this affects `Span::parent`, and any other
// span inspection APIs that would otherwise allow traversing
// the `SyntaxContexts` associated with a span.
//
// None of these user-visible effects should result in any
// cross-crate inconsistencies (getting one behavior in the same
// crate, and a different behavior in another crate) due to the
// limited surface that proc-macros can expose.
//
// IMPORTANT: If this is ever changed, be sure to update
// `rustc_span::hygiene::raw_encode_expn_id` to handle
// encoding `ExpnData` for proc-macro crates.
if s.is_proc_macro {
SyntaxContext::root().encode(s)?;
} else {
span.ctxt.encode(s)?;
}

let span = self.data();
if self.is_dummy() {
return TAG_PARTIAL_SPAN.encode(s);
}

// The Span infrastructure should make sure that this invariant holds:
debug_assert!(span.lo <= span.hi);
Expand All @@ -203,7 +240,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
if !s.source_file_cache.0.contains(span.hi) {
// Unfortunately, macro expansion still sometimes generates Spans
// that malformed in this way.
return TAG_INVALID_SPAN.encode(s);
return TAG_PARTIAL_SPAN.encode(s);
}

let source_files = s.required_source_files.as_mut().expect("Already encoded SourceMap!");
Expand Down Expand Up @@ -259,43 +296,6 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
let len = hi - lo;
len.encode(s)?;

// Don't serialize any `SyntaxContext`s from a proc-macro crate,
// since we don't load proc-macro dependencies during serialization.
// This means that any hygiene information from macros used *within*
// a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
// definition) will be lost.
//
// This can show up in two ways:
//
// 1. Any hygiene information associated with identifier of
// a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
// Since proc-macros can only be invoked from a different crate,
// real code should never need to care about this.
//
// 2. Using `Span::def_site` or `Span::mixed_site` will not
// include any hygiene information associated with the definition
// site. This means that a proc-macro cannot emit a `$crate`
// identifier which resolves to one of its dependencies,
// which also should never come up in practice.
//
// Additionally, this affects `Span::parent`, and any other
// span inspection APIs that would otherwise allow traversing
// the `SyntaxContexts` associated with a span.
//
// None of these user-visible effects should result in any
// cross-crate inconsistencies (getting one behavior in the same
// crate, and a different behavior in another crate) due to the
// limited surface that proc-macros can expose.
//
// IMPORTANT: If this is ever changed, be sure to update
// `rustc_span::hygiene::raw_encode_expn_id` to handle
// encoding `ExpnData` for proc-macro crates.
if s.is_proc_macro {
SyntaxContext::root().encode(s)?;
} else {
span.ctxt.encode(s)?;
}

if tag == TAG_VALID_SPAN_FOREIGN {
// This needs to be two lines to avoid holding the `s.source_file_cache`
// while calling `cnum.encode(s)`
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,4 @@ struct GeneratorData<'tcx> {
// Tags used for encoding Spans:
const TAG_VALID_SPAN_LOCAL: u8 = 0;
const TAG_VALID_SPAN_FOREIGN: u8 = 1;
const TAG_INVALID_SPAN: u8 = 2;
const TAG_PARTIAL_SPAN: u8 = 2;
7 changes: 5 additions & 2 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,8 +1077,11 @@ impl<'a> Parser<'a> {
let span = expr.span;

match &expr.kind {
// Not gated to supporte things like `doc = $expr` that work on stable.
_ if is_interpolated_expr => {}
// Not gated to support things like `doc = $expr` that work on stable.
// Do not gate in `capture_cfg` mode, since we flatten all nontemrinals
// before parsing. `capture_cfg` mode is only used to reparse existing
// tokens, so the gating will be performed by the initial parse
_ if is_interpolated_expr || self.capture_cfg => {}
ExprKind::Lit(lit) if lit.kind.is_unsuffixed() => {}
_ => self.sess.gated_spans.gate(sym::extended_key_value_attributes, span),
}
Expand Down
29 changes: 1 addition & 28 deletions library/alloc/src/collections/vec_deque/into_iter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt;
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
use core::iter::{FusedIterator, TrustedLen};

use super::VecDeque;

Expand Down Expand Up @@ -36,22 +36,6 @@ impl<T> Iterator for IntoIter<T> {
let len = self.inner.len();
(len, Some(len))
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
// that is in bounds.
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
// multiple repeated reads of the same index would be safe and the
// values are !Drop, thus won't suffer from double drops.
unsafe {
let idx = self.inner.wrap_add(self.inner.tail, idx);
self.inner.buffer_read(idx)
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -74,14 +58,3 @@ impl<T> FusedIterator for IntoIter<T> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for IntoIter<T> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
// and thus we can't implement drop-handling
unsafe impl<T> TrustedRandomAccess for IntoIter<T>
where
T: Copy,
{
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
25 changes: 1 addition & 24 deletions library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
fmt,
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
mem::{self, MaybeUninit},
ops::Range,
ptr,
Expand Down Expand Up @@ -130,18 +130,6 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// SAFETY: Callers are only allowed to pass an index that is in bounds
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
// multiple repeated reads of the same index would be safe and the
// values aree !Drop, thus won't suffer from double drops.
unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
}
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
Expand Down Expand Up @@ -196,17 +184,6 @@ impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
// and thus we can't implement drop-handling
unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
where
T: Copy,
{
const MAY_HAVE_SIDE_EFFECT: bool = false;
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
fn clone(&self) -> Self {
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ impl<'a> Builder<'a> {
tool::Rustfmt,
tool::Miri,
tool::CargoMiri,
native::Lld
native::Lld,
native::CrtBeginEnd
),
Kind::Check | Kind::Clippy { .. } | Kind::Fix | Kind::Format => describe!(
check::Std,
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,9 @@ fn copy_self_contained_objects(
DependencyType::TargetSelfContained,
);
}
let crt_path = builder.ensure(native::CrtBeginEnd { target });
for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] {
let src = compiler_file(builder, builder.cc(target), target, obj);
let src = crt_path.join(obj);
let target = libdir_self_contained.join(obj);
builder.copy(&src, &target);
target_deps.push((target, DependencyType::TargetSelfContained));
Expand Down
66 changes: 66 additions & 0 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,3 +858,69 @@ impl HashStamp {
fs::write(&self.path, self.hash.as_deref().unwrap_or(b""))
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrtBeginEnd {
pub target: TargetSelection,
}

impl Step for CrtBeginEnd {
type Output = PathBuf;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/llvm-project/compiler-rt/lib/crt")
}

fn make_run(run: RunConfig<'_>) {
run.builder.ensure(CrtBeginEnd { target: run.target });
}

/// Build crtbegin.o/crtend.o for musl target.
fn run(self, builder: &Builder<'_>) -> Self::Output {
let out_dir = builder.native_dir(self.target).join("crt");

if builder.config.dry_run {
return out_dir;
}

let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c");
let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c");
if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o"))
&& up_to_date(&crtend_src, &out_dir.join("crtendS.o"))
{
return out_dir;
}

builder.info("Building crtbegin.o and crtend.o");
t!(fs::create_dir_all(&out_dir));

let mut cfg = cc::Build::new();

if let Some(ar) = builder.ar(self.target) {
cfg.archiver(ar);
}
cfg.compiler(builder.cc(self.target));
cfg.cargo_metadata(false)
.out_dir(&out_dir)
.target(&self.target.triple)
.host(&builder.config.build.triple)
.warnings(false)
.debug(false)
.opt_level(3)
.file(crtbegin_src)
.file(crtend_src);

// Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt
// Currently only consumer of those objects is musl, which use .init_array/.fini_array
// instead of .ctors/.dtors
cfg.flag("-std=c11")
.define("CRT_HAS_INITFINI_ARRAY", None)
.define("EH_USE_FRAME_REGISTRY", None);

cfg.compile("crt");

t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o")));
t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o")));
out_dir
}
}
6 changes: 5 additions & 1 deletion src/ci/docker/host-x86_64/dist-various-1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ ENV TARGETS=$TARGETS,armv7a-none-eabi
# riscv targets currently do not need a C compiler, as compiler_builtins
# doesn't currently have it enabled, and the riscv gcc compiler is not
# installed.
ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft" \
CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm" \
CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp" \
CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a" \
CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc \
CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc \
Expand Down
10 changes: 8 additions & 2 deletions src/ci/docker/host-x86_64/dist-various-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ ENV \
AR_x86_64_pc_solaris=x86_64-pc-solaris2.10-ar \
CC_x86_64_pc_solaris=x86_64-pc-solaris2.10-gcc \
CXX_x86_64_pc_solaris=x86_64-pc-solaris2.10-g++ \
AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \
CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \
CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-8 \
CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-8 \
AR_x86_64_fortanix_unknown_sgx=ar \
Expand All @@ -68,8 +71,10 @@ COPY host-x86_64/dist-various-2/shared.sh /tmp/
COPY host-x86_64/dist-various-2/build-fuchsia-toolchain.sh /tmp/
RUN /tmp/build-fuchsia-toolchain.sh
COPY host-x86_64/dist-various-2/build-solaris-toolchain.sh /tmp/
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386
RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 pc
# Build deprecated target 'x86_64-sun-solaris2.10' until removed
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 sun
RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun
COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh

Expand Down Expand Up @@ -99,6 +104,7 @@ ENV TARGETS=$TARGETS,wasm32-unknown-unknown
ENV TARGETS=$TARGETS,wasm32-wasi
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
ENV TARGETS=$TARGETS,x86_64-pc-solaris
ENV TARGETS=$TARGETS,x86_64-sun-solaris
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx
ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda
Expand Down
Loading