diff options
| author | Michael Bradshaw <mjbshaw@google.com> | 2018-09-29 19:51:09 -0700 |
|---|---|---|
| committer | Michael Bradshaw <mjbshaw@google.com> | 2018-09-29 19:51:09 -0700 |
| commit | 43cc32fbb2506eff0090e894c1e8a46b62a8eb0b (patch) | |
| tree | ac301fe1be819c25d833880da0ab32bf550016eb /src/librustc_codegen_llvm | |
| parent | aec5330082a0c4664abf0f6604c1b05768a90234 (diff) | |
| parent | 9653f790333d1270f36f1614e85d8a7b54193e75 (diff) | |
| download | rust-43cc32fbb2506eff0090e894c1e8a46b62a8eb0b.tar.gz rust-43cc32fbb2506eff0090e894c1e8a46b62a8eb0b.zip | |
Merge branch 'master' into drop
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/asm.rs | 8 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/back/link.rs | 12 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/back/write.rs | 2 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/builder.rs | 16 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/debuginfo/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/declare.rs | 4 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/diagnostics.rs | 22 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/ffi.rs | 6 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/block.rs | 48 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/place.rs | 9 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/rvalue.rs | 2 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/statement.rs | 6 |
12 files changed, 62 insertions, 75 deletions
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index 5d27f8eab3e..f1bb41bceba 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -30,7 +30,7 @@ pub fn codegen_inline_asm( ia: &hir::InlineAsm, outputs: Vec<PlaceRef<'ll, 'tcx>>, mut inputs: Vec<&'ll Value> -) { +) -> bool { let mut ext_constraints = vec![]; let mut output_types = vec![]; @@ -97,6 +97,10 @@ pub fn codegen_inline_asm( ia.alignstack, dialect ); + if r.is_none() { + return false; + } + let r = r.unwrap(); // Again, based on how many outputs we have let outputs = ia.outputs.iter().zip(&outputs).filter(|&(ref o, _)| !o.is_indirect); @@ -117,6 +121,8 @@ pub fn codegen_inline_asm( llvm::LLVMSetMetadata(r, kind, llvm::LLVMMDNodeInContext(bx.cx.llcx, &val, 1)); } + + return true; } pub fn codegen_global_asm<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 8248385c127..ce52fe00b0e 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -47,7 +47,8 @@ use std::str; use syntax::attr; pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default_output_for_target, - invalid_output_for_target, out_filename, check_file_is_writeable}; + invalid_output_for_target, out_filename, check_file_is_writeable, + filename_for_metadata}; // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled @@ -218,15 +219,6 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool { false } -fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilenames) -> PathBuf { - let out_filename = outputs.single_output_file.clone() - .unwrap_or(outputs - .out_directory - .join(&format!("lib{}{}.rmeta", crate_name, sess.opts.cg.extra_filename))); - check_file_is_writeable(&out_filename, sess); - out_filename -} - pub(crate) fn each_linked_rlib(sess: &Session, info: &CrateInfo, f: &mut dyn FnMut(CrateNum, &Path)) -> Result<(), String> { diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 447b505e79c..02ef690b942 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -196,6 +196,7 @@ pub fn target_machine_factory(sess: &Session, find_features: bool) let features = CString::new(features).unwrap(); let is_pie_binary = !find_features && is_pie_binary(sess); let trap_unreachable = sess.target.target.options.trap_unreachable; + let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes; let asm_comments = sess.asm_comments(); @@ -213,6 +214,7 @@ pub fn target_machine_factory(sess: &Session, find_features: bool) trap_unreachable, singlethread, asm_comments, + emit_stack_size_section, ) }; diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index e3526a5a2ee..77de88997e4 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -737,7 +737,7 @@ impl Builder<'a, 'll, 'tcx> { pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char, inputs: &[&'ll Value], output: &'ll Type, volatile: bool, alignstack: bool, - dia: AsmDialect) -> &'ll Value { + dia: AsmDialect) -> Option<&'ll Value> { self.count_insn("inlineasm"); let volatile = if volatile { llvm::True } @@ -753,9 +753,17 @@ impl Builder<'a, 'll, 'tcx> { debug!("Asm Output Type: {:?}", output); let fty = Type::func(&argtys[..], output); unsafe { - let v = llvm::LLVMRustInlineAsm( - fty, asm, cons, volatile, alignstack, dia); - self.call(v, inputs, None) + // Ask LLVM to verify that the constraints are well-formed. + let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons); + debug!("Constraint verification result: {:?}", constraints_ok); + if constraints_ok == llvm::True { + let v = llvm::LLVMRustInlineAsm( + fty, asm, cons, volatile, alignstack, dia); + Some(self.call(v, inputs, None)) + } else { + // LLVM has detected an issue with our constaints, bail out + None + } } } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 7b0c413e857..99919a940b4 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -279,7 +279,7 @@ pub fn create_function_debug_context( } None => {} }; - if cx.layout_of(sig.output()).abi.is_uninhabited() { + if cx.layout_of(sig.output()).abi == ty::layout::Abi::Uninhabited { flags = flags | DIFlags::FlagNoReturn; } diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 7141c9ece89..5e743ac51bc 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -23,7 +23,7 @@ use llvm; use llvm::AttributePlace::Function; use rustc::ty::{self, Ty}; -use rustc::ty::layout::LayoutOf; +use rustc::ty::layout::{self, LayoutOf}; use rustc::session::config::Sanitizer; use rustc_data_structures::small_c_str::SmallCStr; use rustc_target::spec::PanicStrategy; @@ -137,7 +137,7 @@ pub fn declare_fn( let fty = FnType::new(cx, sig, &[]); let llfn = declare_raw_fn(cx, name, fty.llvm_cconv(), fty.llvm_type(cx)); - if cx.layout_of(sig.output()).abi.is_uninhabited() { + if cx.layout_of(sig.output()).abi == layout::Abi::Uninhabited { llvm::Attribute::NoReturn.apply_llfn(Function, llfn); } diff --git a/src/librustc_codegen_llvm/diagnostics.rs b/src/librustc_codegen_llvm/diagnostics.rs index 94776f17c79..242b7a1a119 100644 --- a/src/librustc_codegen_llvm/diagnostics.rs +++ b/src/librustc_codegen_llvm/diagnostics.rs @@ -47,4 +47,26 @@ unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok! ``` "##, +E0668: r##" +Malformed inline assembly rejected by LLVM. + +LLVM checks the validity of the constraints and the assembly string passed to +it. This error implies that LLVM seems something wrong with the inline +assembly call. + +In particular, it can happen if you forgot the closing bracket of a register +constraint (see issue #51430): +```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) +#![feature(asm)] + +fn main() { + let rax: u64; + unsafe { + asm!("" :"={rax"(rax)); + println!("Accumulator is: {}", rax); + } +} +``` +"##, + } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index a5f4137c62b..8485db4210c 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1208,6 +1208,9 @@ extern "C" { AlignStack: Bool, Dialect: AsmDialect) -> &Value; + pub fn LLVMRustInlineAsmVerify(Ty: &Type, + Constraints: *const c_char) + -> Bool; pub fn LLVMRustDebugMetadataVersion() -> u32; pub fn LLVMRustVersionMajor() -> u32; @@ -1460,7 +1463,8 @@ extern "C" { DataSections: bool, TrapUnreachable: bool, Singlethread: bool, - AsmComments: bool) + AsmComments: bool, + EmitStackSizeSection: bool) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); pub fn LLVMRustAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>, M: &'a Module); diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 709fceb4925..a534b4e478f 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -482,54 +482,6 @@ impl FunctionCx<'a, 'll, 'tcx> { _ => FnType::new(bx.cx, sig, &extra_args) }; - // emit a panic instead of instantiating an uninhabited type - if (intrinsic == Some("init") || intrinsic == Some("uninit")) && - fn_ty.ret.layout.abi.is_uninhabited() - { - let loc = bx.sess().source_map().lookup_char_pos(span.lo()); - let filename = Symbol::intern(&loc.file.name.to_string()).as_str(); - let filename = C_str_slice(bx.cx, filename); - let line = C_u32(bx.cx, loc.line as u32); - let col = C_u32(bx.cx, loc.col.to_usize() as u32 + 1); - let align = tcx.data_layout.aggregate_align - .max(tcx.data_layout.i32_align) - .max(tcx.data_layout.pointer_align); - - let str = format!( - "Attempted to instantiate uninhabited type {} using mem::{}", - sig.output(), - if intrinsic == Some("init") { "zeroed" } else { "uninitialized" } - ); - let msg_str = Symbol::intern(&str).as_str(); - let msg_str = C_str_slice(bx.cx, msg_str); - let msg_file_line_col = C_struct(bx.cx, - &[msg_str, filename, line, col], - false); - let msg_file_line_col = consts::addr_of(bx.cx, - msg_file_line_col, - align, - Some("panic_loc")); - - // Obtain the panic entry point. - let def_id = - common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); - let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = FnType::of_instance(bx.cx, &instance); - let llfn = callee::get_fn(bx.cx, instance); - - // Codegen the actual panic invoke/call. - do_call( - self, - bx, - fn_ty, - llfn, - &[msg_file_line_col], - destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)), - cleanup, - ); - return; - } - // The arguments we'll be passing. Plus one to account for outptr, if used. let arg_count = fn_ty.args.len() + fn_ty.ret.is_indirect() as usize; let mut llargs = Vec::with_capacity(arg_count); diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index bc6ebd360e8..c781b456af6 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -173,10 +173,7 @@ impl PlaceRef<'ll, 'tcx> { let cx = bx.cx; let field = self.layout.field(cx, ix); let offset = self.layout.fields.offset(ix); - let effective_field_align = self.align - .min(self.layout.align) - .min(field.align) - .restrict_for_offset(offset); + let effective_field_align = self.align.restrict_for_offset(offset); let simple = || { // Unions and newtypes only use an offset of 0. @@ -278,7 +275,7 @@ impl PlaceRef<'ll, 'tcx> { /// Obtain the actual discriminant of a value. pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> &'ll Value { let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx); - if self.layout.abi.is_uninhabited() { + if self.layout.abi == layout::Abi::Uninhabited { return C_undef(cast_to); } match self.layout.variants { @@ -341,7 +338,7 @@ impl PlaceRef<'ll, 'tcx> { /// Set the discriminant for a new value of the given case of the given /// representation. pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) { - if self.layout.for_variant(bx.cx, variant_index).abi.is_uninhabited() { + if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited { return; } match self.layout.variants { diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index fa22bdff94d..c3ec347f608 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -290,7 +290,7 @@ impl FunctionCx<'a, 'll, 'tcx> { mir::CastKind::Misc => { assert!(cast.is_llvm_immediate()); let ll_t_out = cast.immediate_llvm_type(bx.cx); - if operand.layout.abi.is_uninhabited() { + if operand.layout.abi == layout::Abi::Uninhabited { return (bx, OperandRef { val: OperandValue::Immediate(C_undef(ll_t_out)), layout: cast, diff --git a/src/librustc_codegen_llvm/mir/statement.rs b/src/librustc_codegen_llvm/mir/statement.rs index b4eb7615f98..6bd41bfe16f 100644 --- a/src/librustc_codegen_llvm/mir/statement.rs +++ b/src/librustc_codegen_llvm/mir/statement.rs @@ -86,7 +86,11 @@ impl FunctionCx<'a, 'll, 'tcx> { self.codegen_operand(&bx, input).immediate() }).collect(); - asm::codegen_inline_asm(&bx, asm, outputs, input_vals); + let res = asm::codegen_inline_asm(&bx, asm, outputs, input_vals); + if !res { + span_err!(bx.sess(), statement.source_info.span, E0668, + "malformed inline assembly"); + } bx } mir::StatementKind::FakeRead(..) | |
