Skip to content

Commit 21e5b94

Browse files
committed
Auto merge of #108128 - clubby789:builtin-derived-attr, r=jackh726
Properly check for builtin derived code Fixes #108122
2 parents 7aa413d + 90f642b commit 21e5b94

File tree

8 files changed

+60
-34
lines changed

8 files changed

+60
-34
lines changed

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,7 @@ impl<'a> TraitDef<'a> {
761761
let path = cx.path_all(self.span, false, vec![type_ident], self_params);
762762
let self_type = cx.ty_path(path);
763763

764-
let attr = cx.attr_word(sym::automatically_derived, self.span);
765-
let attrs = thin_vec![attr];
764+
let attrs = thin_vec![cx.attr_word(sym::automatically_derived, self.span),];
766765
let opt_trait_ref = Some(trait_ref);
767766

768767
cx.item(

compiler/rustc_middle/src/ty/mod.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use rustc_serialize::{Decodable, Encodable};
4646
use rustc_session::cstore::Untracked;
4747
use rustc_span::hygiene::MacroKind;
4848
use rustc_span::symbol::{kw, sym, Ident, Symbol};
49-
use rustc_span::{ExpnId, Span};
49+
use rustc_span::{ExpnId, ExpnKind, Span};
5050
use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx};
5151
pub use rustc_target::abi::{ReprFlags, ReprOptions};
5252
use rustc_type_ir::WithCachedTypeInfo;
@@ -2444,8 +2444,23 @@ impl<'tcx> TyCtxt<'tcx> {
24442444
None
24452445
}
24462446

2447-
/// If the given `DefId` belongs to a trait that was automatically derived, returns `true`.
2448-
pub fn is_builtin_derive(self, def_id: DefId) -> bool {
2447+
/// Check if the given `DefId` is `#\[automatically_derived\], *and*
2448+
/// whether it was produced by expanding a builtin derive macro.
2449+
pub fn is_builtin_derived(self, def_id: DefId) -> bool {
2450+
if self.is_automatically_derived(def_id)
2451+
&& let Some(def_id) = def_id.as_local()
2452+
&& let outer = self.def_span(def_id).ctxt().outer_expn_data()
2453+
&& matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _))
2454+
&& self.has_attr(outer.macro_def_id.unwrap(), sym::rustc_builtin_macro)
2455+
{
2456+
true
2457+
} else {
2458+
false
2459+
}
2460+
}
2461+
2462+
/// Check if the given `DefId` is `#\[automatically_derived\]`.
2463+
pub fn is_automatically_derived(self, def_id: DefId) -> bool {
24492464
self.has_attr(def_id, sym::automatically_derived)
24502465
}
24512466

compiler/rustc_mir_transform/src/check_packed_ref.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
4242
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
4343
let def_id = self.body.source.instance.def_id();
4444
if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
45-
&& self.tcx.is_builtin_derive(impl_def_id)
45+
&& self.tcx.is_builtin_derived(impl_def_id)
4646
{
4747
// If we ever reach here it means that the generated derive
4848
// code is somehow doing an unaligned reference, which it
4949
// shouldn't do.
50-
unreachable!();
50+
span_bug!(self.source_info.span, "builtin derive created an unaligned reference");
5151
} else {
5252
struct_span_err!(
5353
self.tcx.sess,

compiler/rustc_passes/src/dead.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
259259
/// for discussion).
260260
fn should_ignore_item(&mut self, def_id: DefId) -> bool {
261261
if let Some(impl_of) = self.tcx.impl_of_method(def_id) {
262-
if !self.tcx.has_attr(impl_of, sym::automatically_derived) {
262+
if !self.tcx.is_automatically_derived(impl_of) {
263263
return false;
264264
}
265265

compiler/rustc_passes/src/stability.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
537537
// then it would be "stable" at least for the impl.
538538
// We gate usages of it using `feature(const_trait_impl)` anyways
539539
// so there is no unstable leakage
540-
if self.tcx.is_builtin_derive(def_id.to_def_id()) {
540+
if self.tcx.is_automatically_derived(def_id.to_def_id()) {
541541
return;
542542
}
543543

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2104,7 +2104,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
21042104
// Ignore automatically derived impls and `!Trait` impls.
21052105
.filter(|&def_id| {
21062106
self.tcx.impl_polarity(def_id) != ty::ImplPolarity::Negative
2107-
|| self.tcx.is_builtin_derive(def_id)
2107+
|| self.tcx.is_automatically_derived(def_id)
21082108
})
21092109
.filter_map(|def_id| self.tcx.impl_trait_ref(def_id))
21102110
.map(ty::EarlyBinder::subst_identity)

tests/ui/lint/unaligned_references.rs

+17-14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ pub struct Packed2 {
1313
z: u8,
1414
}
1515

16+
trait Foo {
17+
fn evil(&self);
18+
}
19+
20+
// Test for #108122
21+
#[automatically_derived]
22+
impl Foo for Packed2 {
23+
fn evil(&self) {
24+
unsafe {
25+
&self.x; //~ ERROR reference to packed field
26+
}
27+
}
28+
}
29+
1630
fn main() {
1731
unsafe {
1832
let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };
@@ -37,6 +51,7 @@ fn main() {
3751
let _ = &packed2.x; //~ ERROR reference to packed field
3852
let _ = &packed2.y; // ok, has align 2 in packed(2) struct
3953
let _ = &packed2.z; // ok, has align 1
54+
packed2.evil();
4055
}
4156

4257
unsafe {
@@ -71,22 +86,10 @@ fn main() {
7186
#[repr(packed)]
7287
struct Misalign<T>(u8, T);
7388

74-
let m1 = Misalign(
75-
0,
76-
Wrapper {
77-
a: U16(10),
78-
b: HasDrop,
79-
},
80-
);
89+
let m1 = Misalign(0, Wrapper { a: U16(10), b: HasDrop });
8190
let _ref = &m1.1.a; //~ ERROR reference to packed field
8291

83-
let m2 = Misalign(
84-
0,
85-
Wrapper2 {
86-
a: U16(10),
87-
b: HasDrop,
88-
},
89-
);
92+
let m2 = Misalign(0, Wrapper2 { a: U16(10), b: HasDrop });
9093
let _ref = &m2.1.a; //~ ERROR reference to packed field
9194
}
9295
}
+19-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
error[E0793]: reference to packed field is unaligned
2-
--> $DIR/unaligned_references.rs:20:17
2+
--> $DIR/unaligned_references.rs:25:13
3+
|
4+
LL | &self.x;
5+
| ^^^^^^^
6+
|
7+
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
8+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
9+
10+
error[E0793]: reference to packed field is unaligned
11+
--> $DIR/unaligned_references.rs:34:17
312
|
413
LL | let _ = &good.ptr;
514
| ^^^^^^^^^
@@ -8,7 +17,7 @@ LL | let _ = &good.ptr;
817
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
918

1019
error[E0793]: reference to packed field is unaligned
11-
--> $DIR/unaligned_references.rs:21:17
20+
--> $DIR/unaligned_references.rs:35:17
1221
|
1322
LL | let _ = &good.data;
1423
| ^^^^^^^^^^
@@ -17,7 +26,7 @@ LL | let _ = &good.data;
1726
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
1827

1928
error[E0793]: reference to packed field is unaligned
20-
--> $DIR/unaligned_references.rs:23:17
29+
--> $DIR/unaligned_references.rs:37:17
2130
|
2231
LL | let _ = &good.data as *const _;
2332
| ^^^^^^^^^^
@@ -26,7 +35,7 @@ LL | let _ = &good.data as *const _;
2635
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
2736

2837
error[E0793]: reference to packed field is unaligned
29-
--> $DIR/unaligned_references.rs:24:27
38+
--> $DIR/unaligned_references.rs:38:27
3039
|
3140
LL | let _: *const _ = &good.data;
3241
| ^^^^^^^^^^
@@ -35,7 +44,7 @@ LL | let _: *const _ = &good.data;
3544
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
3645

3746
error[E0793]: reference to packed field is unaligned
38-
--> $DIR/unaligned_references.rs:26:17
47+
--> $DIR/unaligned_references.rs:40:17
3948
|
4049
LL | let _ = good.data.clone();
4150
| ^^^^^^^^^^^^^^^^^
@@ -44,7 +53,7 @@ LL | let _ = good.data.clone();
4453
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
4554

4655
error[E0793]: reference to packed field is unaligned
47-
--> $DIR/unaligned_references.rs:28:17
56+
--> $DIR/unaligned_references.rs:42:17
4857
|
4958
LL | let _ = &good.data2[0];
5059
| ^^^^^^^^^^^^^^
@@ -53,7 +62,7 @@ LL | let _ = &good.data2[0];
5362
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
5463

5564
error[E0793]: reference to packed field is unaligned
56-
--> $DIR/unaligned_references.rs:37:17
65+
--> $DIR/unaligned_references.rs:51:17
5766
|
5867
LL | let _ = &packed2.x;
5968
| ^^^^^^^^^^
@@ -62,7 +71,7 @@ LL | let _ = &packed2.x;
6271
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
6372

6473
error[E0793]: reference to packed field is unaligned
65-
--> $DIR/unaligned_references.rs:81:20
74+
--> $DIR/unaligned_references.rs:90:20
6675
|
6776
LL | let _ref = &m1.1.a;
6877
| ^^^^^^^
@@ -71,14 +80,14 @@ LL | let _ref = &m1.1.a;
7180
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
7281

7382
error[E0793]: reference to packed field is unaligned
74-
--> $DIR/unaligned_references.rs:90:20
83+
--> $DIR/unaligned_references.rs:93:20
7584
|
7685
LL | let _ref = &m2.1.a;
7786
| ^^^^^^^
7887
|
7988
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
8089
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
8190

82-
error: aborting due to 9 previous errors
91+
error: aborting due to 10 previous errors
8392

8493
For more information about this error, try `rustc --explain E0793`.

0 commit comments

Comments
 (0)