Skip to content

Commit a440aec

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 db4d6e1 commit a440aec

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

src/librustc_codegen_llvm/type_of.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,13 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
311311
F64 => cx.type_f64(),
312312
Pointer => {
313313
// If we know the alignment, pick something better than i8.
314-
let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
315-
cx.type_pointee_for_align(pointee.align)
316-
} else {
317-
cx.type_i8()
318-
};
319-
cx.type_ptr_to(pointee, AddressSpace::default())
314+
let (pointee, address_space) =
315+
if let Some(pointee) = self.pointee_info_at(cx, offset) {
316+
(cx.type_pointee_for_align(pointee.align), pointee.address_space)
317+
} else {
318+
(cx.type_i8(), AddressSpace::default())
319+
};
320+
cx.type_ptr_to(pointee, address_space)
320321
}
321322
}
322323
}

src/librustc_middle/ty/layout.rs

+31-4
Original file line numberDiff line numberDiff line change
@@ -2146,16 +2146,36 @@ where
21462146
}
21472147

21482148
fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
2149-
match this.ty.kind {
2149+
let addr_space_of_ty = |ty: Ty<'tcx>| {
2150+
if ty.is_fn() {
2151+
cx.data_layout().instruction_address_space
2152+
} else {
2153+
AddressSpace::default()
2154+
}
2155+
};
2156+
2157+
let pointee_info = match this.ty.kind {
21502158
ty::RawPtr(mt) if offset.bytes() == 0 => {
21512159
cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo {
21522160
size: layout.size,
21532161
align: layout.align.abi,
21542162
safe: None,
2163+
address_space: addr_space_of_ty(mt.ty),
2164+
})
2165+
}
2166+
ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
2167+
cx.layout_of(cx.tcx().mk_fn_ptr(fn_sig)).to_result().ok().map(|layout| {
2168+
PointeeInfo {
2169+
size: layout.size,
2170+
align: layout.align.abi,
2171+
safe: None,
2172+
address_space: cx.data_layout().instruction_address_space,
2173+
}
21552174
})
21562175
}
2157-
21582176
ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
2177+
let address_space = addr_space_of_ty(ty);
2178+
21592179
let tcx = cx.tcx();
21602180
let is_freeze = ty.is_freeze(tcx, cx.param_env(), DUMMY_SP);
21612181
let kind = match mt {
@@ -2190,6 +2210,7 @@ where
21902210
size: layout.size,
21912211
align: layout.align.abi,
21922212
safe: Some(kind),
2213+
address_space,
21932214
})
21942215
}
21952216

@@ -2234,7 +2255,9 @@ where
22342255
result = field.to_result().ok().and_then(|field| {
22352256
if ptr_end <= field_start + field.size {
22362257
// We found the right field, look inside it.
2237-
field.pointee_info_at(cx, offset - field_start)
2258+
let field_info =
2259+
field.pointee_info_at(cx, offset - field_start);
2260+
field_info
22382261
} else {
22392262
None
22402263
}
@@ -2257,7 +2280,11 @@ where
22572280

22582281
result
22592282
}
2260-
}
2283+
};
2284+
2285+
debug!("pointee_info_at (offset={:?}, type kind: {:?}) => {:?}", offset, this.ty.kind, pointee_info);
2286+
2287+
pointee_info
22612288
}
22622289
}
22632290

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)