Skip to content

Commit d348eca

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 0bb88c5 commit d348eca

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-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

+30-4
Original file line numberDiff line numberDiff line change
@@ -2148,16 +2148,32 @@ where
21482148
}
21492149

21502150
fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
2151-
match this.ty.kind {
2151+
let addr_space_of_ty = |ty: Ty<'tcx>| {
2152+
if ty.is_fn() { cx.data_layout().instruction_address_space } else { AddressSpace::DATA }
2153+
};
2154+
2155+
let pointee_info = match this.ty.kind {
21522156
ty::RawPtr(mt) if offset.bytes() == 0 => {
21532157
cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo {
21542158
size: layout.size,
21552159
align: layout.align.abi,
21562160
safe: None,
2161+
address_space: addr_space_of_ty(mt.ty),
2162+
})
2163+
}
2164+
ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
2165+
cx.layout_of(cx.tcx().mk_fn_ptr(fn_sig)).to_result().ok().map(|layout| {
2166+
PointeeInfo {
2167+
size: layout.size,
2168+
align: layout.align.abi,
2169+
safe: None,
2170+
address_space: cx.data_layout().instruction_address_space,
2171+
}
21572172
})
21582173
}
2159-
21602174
ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
2175+
let address_space = addr_space_of_ty(ty);
2176+
21612177
let tcx = cx.tcx();
21622178
let is_freeze = ty.is_freeze(tcx.at(DUMMY_SP), cx.param_env());
21632179
let kind = match mt {
@@ -2192,6 +2208,7 @@ where
21922208
size: layout.size,
21932209
align: layout.align.abi,
21942210
safe: Some(kind),
2211+
address_space,
21952212
})
21962213
}
21972214

@@ -2236,7 +2253,9 @@ where
22362253
result = field.to_result().ok().and_then(|field| {
22372254
if ptr_end <= field_start + field.size {
22382255
// We found the right field, look inside it.
2239-
field.pointee_info_at(cx, offset - field_start)
2256+
let field_info =
2257+
field.pointee_info_at(cx, offset - field_start);
2258+
field_info
22402259
} else {
22412260
None
22422261
}
@@ -2259,7 +2278,14 @@ where
22592278

22602279
result
22612280
}
2262-
}
2281+
};
2282+
2283+
debug!(
2284+
"pointee_info_at (offset={:?}, type kind: {:?}) => {:?}",
2285+
offset, this.ty.kind, pointee_info
2286+
);
2287+
2288+
pointee_info
22632289
}
22642290
}
22652291

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)