Skip to content

Commit

Permalink
Fix a bug in the pointer address space assignment code
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dylanmckay committed Jun 23, 2020
1 parent 336322c commit a3ff396
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 16 deletions.
5 changes: 2 additions & 3 deletions src/librustc_codegen_llvm/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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 {
Expand Down
23 changes: 10 additions & 13 deletions src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -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 },
Expand All @@ -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) {
Expand Down

0 comments on commit a3ff396

Please sign in to comment.