From a3ff3965e16aeaa9fb3bdf43254802c0a86cbc9a Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Tue, 23 Jun 2020 18:23:00 +1200 Subject: [PATCH] Fix a bug in the pointer address space assignment code The code was not checking the "function-ness" of the type at the correct level. It was checking the "root type", which may be, say a struct, but would use that exclusively for classifying the address spaces of the fields within the struct. A function pointer within a struct would be incorrectly defined with address space 0 only because its parent struct is in address space 0. This patch also moves the address space classification logic for constants down a layer, which allows removal of the address space parameter from a few functions, and fixes the problem at the source rather than patching over top of it in a method higher up in the call stack. --- src/librustc_codegen_llvm/common.rs | 5 ++--- src/librustc_codegen_llvm/consts.rs | 23 ++++++++++------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 3e82a2db5c772..3c00f14bccb76 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -246,8 +246,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { Scalar::Ptr(ptr) => { let base_addr = match self.tcx.global_alloc(ptr.alloc_id) { GlobalAlloc::Memory(alloc) => { - let init = - const_alloc_to_llvm(self, alloc, self.address_space_of_type(llty)); + let init = const_alloc_to_llvm(self, alloc); let value = match alloc.mutability { Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None), _ => self.static_addr_of(init, alloc.align, None), @@ -297,7 +296,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let llval = self.const_usize(alloc.align.bytes()); unsafe { llvm::LLVMConstIntToPtr(llval, llty) } } else { - let init = const_alloc_to_llvm(self, alloc, address_space); + let init = const_alloc_to_llvm(self, alloc); let base_addr = self.static_addr_of(init, alloc.align, None); let llval = unsafe { diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 3379fce3beb96..0aa0cf33d1c39 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ - read_target_uint, Allocation, ConstValue, ErrorHandled, Pointer, + read_target_uint, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Pointer, }; use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::{self, Instance, Ty}; @@ -24,11 +24,7 @@ use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, use std::ffi::CStr; -pub fn const_alloc_to_llvm( - cx: &CodegenCx<'ll, '_>, - alloc: &Allocation, - address_space: AddressSpace, -) -> &'ll Value { +pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value { let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1); let dl = cx.data_layout(); let pointer_size = dl.pointer_size.bytes() as usize; @@ -57,6 +53,12 @@ pub fn const_alloc_to_llvm( ) .expect("const_alloc_to_llvm: could not read relocation pointer") as u64; + + let address_space = match cx.tcx.global_alloc(alloc_id) { + GlobalAlloc::Function(..) => cx.data_layout().instruction_address_space, + GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) => AddressSpace::DATA, + }; + llvals.push(cx.scalar_to_backend( Pointer::new(alloc_id, Size::from_bytes(ptr_offset)).into(), &Scalar { value: Primitive::Pointer, valid_range: 0..=!0 }, @@ -83,17 +85,12 @@ pub fn codegen_static_initializer( cx: &CodegenCx<'ll, 'tcx>, def_id: DefId, ) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> { - let address_space = if cx.tcx.type_of(def_id).is_fn() { - cx.data_layout().instruction_address_space - } else { - AddressSpace::DATA - }; - let alloc = match cx.tcx.const_eval_poly(def_id)? { ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => alloc, val => bug!("static const eval returned {:#?}", val), }; - Ok((const_alloc_to_llvm(cx, alloc, address_space), alloc)) + + Ok((const_alloc_to_llvm(cx, alloc), alloc)) } fn set_global_alignment(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Align) {