Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
840a576
Move raw string tests into the raw directory
rcoh Mar 28, 2020
4d099e6
Add `-Z dump-mir-dataflow`
ecstatic-morse Mar 28, 2020
edbd7c8
`dump_enabled` takes a `DefId` instead of `MirSource`
ecstatic-morse Mar 28, 2020
c800402
Dump graphviz dataflow results with flag
ecstatic-morse Mar 28, 2020
4d1194c
Ensure output dir for dataflow results exists
ecstatic-morse Mar 28, 2020
629e97a
Improve error messages for raw strings (#60762)
rcoh Mar 28, 2020
c15f86b
Cleanup error messages, improve docstrings
rcoh Mar 29, 2020
82b2989
More raw string tests
rcoh Mar 29, 2020
bceab25
Cleanup match expression
rcoh Mar 29, 2020
20e2190
Clean up redudant conditions and match exprs
rcoh Mar 30, 2020
097e9e5
Add `can_unwind` field to `FnAbi`
wesleywiser Mar 29, 2020
6067315
Ensure LLVM is in the link path for "fulldeps" tests
cuviper Mar 30, 2020
55a5eea
Fix tests to handle debug_assert
rcoh Mar 31, 2020
d45dca3
Use Place directly, it's Copy
spastorino Mar 30, 2020
f026441
Use Place directly on propagate_closure_used_mut_place, it's Copy
spastorino Mar 30, 2020
a67b28a
Use Place directly on borrow_of_local_data, it's Copy
spastorino Mar 30, 2020
32a7618
Use Place directly on remove_never_initialized_mut_locals, it's Copy
spastorino Mar 30, 2020
760bca4
Use Place directly on check_mut_borrowing_layout_constrained_field, i…
spastorino Mar 30, 2020
25528c1
Use Place directly, it's Copy more use cases
spastorino Mar 30, 2020
890b393
Use Place directly, it's Copy even more use cases
spastorino Mar 31, 2020
6a95bf8
Use Place directly on Operand::place and friends, it's Copy
spastorino Mar 31, 2020
f37d2b8
Use Place directly in librustc_mir_build, it's Copy
spastorino Mar 31, 2020
5987b0f
Use Place directly in place_as_reborrow, it's Copy
spastorino Mar 31, 2020
947c1dc
Use Place directly on place_contents_drop_state_cannot_differ, it's Copy
spastorino Mar 31, 2020
017620f
Use Place directly in peek_at, it's Copy
spastorino Mar 31, 2020
afcd7fc
Use Place directly on codegen_drop_terminator, it's Copy
spastorino Mar 31, 2020
5f8a6ed
Use Place directly on make_return_dest, it's Copy
spastorino Mar 31, 2020
1f5338c
Use Place directly in codegen_transmute, it's Copy
spastorino Mar 31, 2020
a865e77
Use Place directly in evaluate_array_len, it's Copy
spastorino Mar 31, 2020
017608f
Use Place directly in codegen_place_to_pointer, it's Copy
spastorino Mar 31, 2020
b46754e
Use Place directly in apply_call_return_effect on framework/tests, it…
spastorino Mar 31, 2020
036626f
Address review feedback
wesleywiser Mar 31, 2020
e39f542
Add git repo address to unstable book
tesuji Apr 1, 2020
84a4633
Rollup merge of #70511 - ecstatic-morse:mir-dataflow-graphviz, r=davi…
Centril Apr 1, 2020
c739465
Rollup merge of #70522 - rcoh:60762-raw-string-errors, r=petrochenkov
Centril Apr 1, 2020
90cecab
Rollup merge of #70547 - wesleywiser:extract_can_unwind, r=eddyb
Centril Apr 1, 2020
43119de
Rollup merge of #70591 - cuviper:fulldeps-library-path, r=Mark-Simula…
Centril Apr 1, 2020
9223bb5
Rollup merge of #70627 - spastorino:use-place-directly-its-copy, r=ol…
Centril Apr 1, 2020
c1419b4
Rollup merge of #70652 - lzutao:patch-1, r=Centril
Centril Apr 1, 2020
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
7 changes: 7 additions & 0 deletions src/librustc_codegen_llvm/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,11 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn);
}

// FIXME(eddyb, wesleywiser): apply this to callsites as well?
if !self.can_unwind {
llvm::Attribute::NoUnwind.apply_llfn(llvm::AttributePlace::Function, llfn);
}

let mut i = 0;
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty);
Expand Down Expand Up @@ -431,6 +436,8 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}

fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
// FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.

let mut i = 0;
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty);
Expand Down
58 changes: 2 additions & 56 deletions src/librustc_codegen_llvm/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::{OptLevel, Sanitizer};
use rustc_session::Session;
use rustc_target::abi::call::Conv;
use rustc_target::spec::PanicStrategy;

use crate::abi::FnAbi;
use crate::attributes;
use crate::llvm::AttributePlace::Function;
use crate::llvm::{self, Attribute};
Expand Down Expand Up @@ -77,12 +74,6 @@ pub fn emit_uwtable(val: &'ll Value, emit: bool) {
Attribute::UWTable.toggle_llfn(Function, val, emit);
}

/// Tell LLVM whether the function can or cannot unwind.
#[inline]
fn unwind(val: &'ll Value, can_unwind: bool) {
Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
}

/// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue.
#[inline]
fn naked(val: &'ll Value, is_naked: bool) {
Expand Down Expand Up @@ -246,12 +237,7 @@ pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) {

/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
/// attributes.
pub fn from_fn_attrs(
cx: &CodegenCx<'ll, 'tcx>,
llfn: &'ll Value,
instance: ty::Instance<'tcx>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) {
pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::Instance<'tcx>) {
let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());

match codegen_fn_attrs.optimize {
Expand Down Expand Up @@ -315,46 +301,6 @@ pub fn from_fn_attrs(
}
sanitize(cx, codegen_fn_attrs.flags, llfn);

unwind(
llfn,
if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
// In panic=abort mode we assume nothing can unwind anywhere, so
// optimize based on this!
false
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
// If a specific #[unwind] attribute is present, use that.
true
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
// Special attribute for allocator functions, which can't unwind.
false
} else {
if fn_abi.conv == Conv::Rust {
// Any Rust method (or `extern "Rust" fn` or `extern
// "rust-call" fn`) is explicitly allowed to unwind
// (unless it has no-unwind attribute, handled above).
true
} else {
// Anything else is either:
//
// 1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or
//
// 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
//
// Foreign items (case 1) are assumed to not unwind; it is
// UB otherwise. (At least for now; see also
// rust-lang/rust#63909 and Rust RFC 2753.)
//
// Items defined in Rust with non-Rust ABIs (case 2) are also
// not supposed to unwind. Whether this should be enforced
// (versus stating it is UB) and *how* it would be enforced
// is currently under discussion; see rust-lang/rust#58794.
//
// In either case, we mark item as explicitly nounwind.
false
}
},
);

// Always annotate functions with the target-cpu they are compiled for.
// Without this, ThinLTO won't inline Rust functions into Clang generated
// functions (because Clang annotates functions this way too).
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
let llfn = cx.declare_fn(&sym, &fn_abi);
debug!("get_fn: not casting pointer!");

attributes::from_fn_attrs(cx, llfn, instance, &fn_abi);
attributes::from_fn_attrs(cx, llfn, instance);

let instance_def_id = instance.def_id();

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {

debug!("predefine_fn: instance = {:?}", instance);

attributes::from_fn_attrs(self, lldecl, instance, &fn_abi);
attributes::from_fn_attrs(self, lldecl, instance);

self.instances.borrow_mut().insert(instance, lldecl);
}
Expand Down
60 changes: 57 additions & 3 deletions src/librustc_middle/ty/layout.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::ich::StableHashingContext;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
use crate::ty::subst::Subst;
use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
Expand All @@ -15,7 +16,7 @@ use rustc_target::abi::call::{
ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
};
pub use rustc_target::abi::*;
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec};
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy};

use std::cmp;
use std::fmt;
Expand Down Expand Up @@ -2368,11 +2369,55 @@ where
sig: ty::PolyFnSig<'tcx>,
extra_args: &[Ty<'tcx>],
caller_location: Option<Ty<'tcx>>,
codegen_fn_attr_flags: CodegenFnAttrFlags,
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
) -> Self;
fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
}

fn fn_can_unwind(
panic_strategy: PanicStrategy,
codegen_fn_attr_flags: CodegenFnAttrFlags,
call_conv: Conv,
) -> bool {
if panic_strategy != PanicStrategy::Unwind {
// In panic=abort mode we assume nothing can unwind anywhere, so
// optimize based on this!
false
} else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::UNWIND) {
// If a specific #[unwind] attribute is present, use that.
true
} else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
// Special attribute for allocator functions, which can't unwind.
false
} else {
if call_conv == Conv::Rust {
// Any Rust method (or `extern "Rust" fn` or `extern
// "rust-call" fn`) is explicitly allowed to unwind
// (unless it has no-unwind attribute, handled above).
true
} else {
// Anything else is either:
//
// 1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or
//
// 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
//
// Foreign items (case 1) are assumed to not unwind; it is
// UB otherwise. (At least for now; see also
// rust-lang/rust#63909 and Rust RFC 2753.)
//
// Items defined in Rust with non-Rust ABIs (case 2) are also
// not supposed to unwind. Whether this should be enforced
// (versus stating it is UB) and *how* it would be enforced
// is currently under discussion; see rust-lang/rust#58794.
//
// In either case, we mark item as explicitly nounwind.
false
}
}
}

impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
where
C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
Expand All @@ -2382,7 +2427,12 @@ where
+ HasParamEnv<'tcx>,
{
fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
call::FnAbi::new_internal(cx, sig, extra_args, None, |ty, _| ArgAbi::new(cx.layout_of(ty)))
// Assume that fn pointers may always unwind
let codegen_fn_attr_flags = CodegenFnAttrFlags::UNWIND;

call::FnAbi::new_internal(cx, sig, extra_args, None, codegen_fn_attr_flags, |ty, _| {
ArgAbi::new(cx.layout_of(ty))
})
}

fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
Expand All @@ -2394,7 +2444,9 @@ where
None
};

call::FnAbi::new_internal(cx, sig, extra_args, caller_location, |ty, arg_idx| {
let attrs = cx.tcx().codegen_fn_attrs(instance.def_id()).flags;

call::FnAbi::new_internal(cx, sig, extra_args, caller_location, attrs, |ty, arg_idx| {
let mut layout = cx.layout_of(ty);
// Don't pass the vtable, it's not an argument of the virtual fn.
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
Expand Down Expand Up @@ -2450,6 +2502,7 @@ where
sig: ty::PolyFnSig<'tcx>,
extra_args: &[Ty<'tcx>],
caller_location: Option<Ty<'tcx>>,
codegen_fn_attr_flags: CodegenFnAttrFlags,
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
) -> Self {
debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
Expand Down Expand Up @@ -2639,6 +2692,7 @@ where
c_variadic: sig.c_variadic,
fixed_count: inputs.len(),
conv,
can_unwind: fn_can_unwind(cx.tcx().sess.panic_strategy(), codegen_fn_attr_flags, conv),
};
fn_abi.adjust_for_abi(cx, sig.abi);
fn_abi
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_target/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,8 @@ pub struct FnAbi<'a, Ty> {
pub fixed_count: usize,

pub conv: Conv,

pub can_unwind: bool,
}

impl<'a, Ty> FnAbi<'a, Ty> {
Expand Down