Skip to content

Commit 5581ce6

Browse files
committed
[AVR] Ensure that function pointers stored within aggregates are annotated with the correct space
Before this patch, a function pointer stored within an aggregate like a struct or an enum would always have the default address space `0`. This patch removes this assumption and instead, introspects the inner type being pointed at, storing the target address space in the PointeeInfo struct so that downstream users may query it.
1 parent 8ae5ead commit 5581ce6

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

src/librustc_codegen_llvm/type_of.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::bug;
77
use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
88
use rustc_middle::ty::print::obsolete::DefPathBasedNames;
99
use rustc_middle::ty::{self, Ty, TypeFoldable};
10-
use rustc_target::abi::{Abi, Align, FieldsShape};
10+
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
1111
use rustc_target::abi::{Int, Pointer, F32, F64};
1212
use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAndLayoutMethods, Variants};
1313

@@ -310,12 +310,13 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
310310
F64 => cx.type_f64(),
311311
Pointer => {
312312
// If we know the alignment, pick something better than i8.
313-
let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
314-
cx.type_pointee_for_align(pointee.align)
315-
} else {
316-
cx.type_i8()
317-
};
318-
cx.type_ptr_to(pointee)
313+
let (pointee, address_space) =
314+
if let Some(pointee) = self.pointee_info_at(cx, offset) {
315+
(cx.type_pointee_for_align(pointee.align), pointee.address_space)
316+
} else {
317+
(cx.type_i8(), AddressSpace::DATA)
318+
};
319+
cx.type_ptr_to_ext(pointee, address_space)
319320
}
320321
}
321322
}

src/librustc_middle/ty/layout.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -2166,16 +2166,31 @@ where
21662166
}
21672167

21682168
fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
2169-
match this.ty.kind {
2169+
let addr_space_of_ty = |ty: Ty<'tcx>| {
2170+
if ty.is_fn() { cx.data_layout().instruction_address_space } else { AddressSpace::DATA }
2171+
};
2172+
2173+
let pointee_info = match this.ty.kind {
21702174
ty::RawPtr(mt) if offset.bytes() == 0 => {
21712175
cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo {
21722176
size: layout.size,
21732177
align: layout.align.abi,
21742178
safe: None,
2179+
address_space: addr_space_of_ty(mt.ty),
2180+
})
2181+
}
2182+
ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
2183+
cx.layout_of(cx.tcx().mk_fn_ptr(fn_sig)).to_result().ok().map(|layout| {
2184+
PointeeInfo {
2185+
size: layout.size,
2186+
align: layout.align.abi,
2187+
safe: None,
2188+
address_space: cx.data_layout().instruction_address_space,
2189+
}
21752190
})
21762191
}
2177-
21782192
ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
2193+
let address_space = addr_space_of_ty(ty);
21792194
let tcx = cx.tcx();
21802195
let is_freeze = ty.is_freeze(tcx.at(DUMMY_SP), cx.param_env());
21812196
let kind = match mt {
@@ -2210,6 +2225,7 @@ where
22102225
size: layout.size,
22112226
align: layout.align.abi,
22122227
safe: Some(kind),
2228+
address_space,
22132229
})
22142230
}
22152231

@@ -2254,7 +2270,9 @@ where
22542270
result = field.to_result().ok().and_then(|field| {
22552271
if ptr_end <= field_start + field.size {
22562272
// We found the right field, look inside it.
2257-
field.pointee_info_at(cx, offset - field_start)
2273+
let field_info =
2274+
field.pointee_info_at(cx, offset - field_start);
2275+
field_info
22582276
} else {
22592277
None
22602278
}
@@ -2277,7 +2295,14 @@ where
22772295

22782296
result
22792297
}
2280-
}
2298+
};
2299+
2300+
debug!(
2301+
"pointee_info_at (offset={:?}, type kind: {:?}) => {:?}",
2302+
offset, this.ty.kind, pointee_info
2303+
);
2304+
2305+
pointee_info
22812306
}
22822307
}
22832308

src/librustc_target/abi/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ impl<T, E> MaybeResult<T> for Result<T, E> {
10241024
}
10251025
}
10261026

1027-
#[derive(Copy, Clone, PartialEq, Eq)]
1027+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
10281028
pub enum PointerKind {
10291029
/// Most general case, we know no restrictions to tell LLVM.
10301030
Shared,
@@ -1039,11 +1039,12 @@ pub enum PointerKind {
10391039
UniqueOwned,
10401040
}
10411041

1042-
#[derive(Copy, Clone)]
1042+
#[derive(Copy, Clone, Debug)]
10431043
pub struct PointeeInfo {
10441044
pub size: Size,
10451045
pub align: Align,
10461046
pub safe: Option<PointerKind>,
1047+
pub address_space: AddressSpace,
10471048
}
10481049

10491050
pub trait TyAndLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {

0 commit comments

Comments
 (0)