Skip to content

Commit

Permalink
Forbid implicit nested statics in thread local statics
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Apr 2, 2024
1 parent 6c5c48e commit 64b75f7
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 20 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ const_eval_mut_deref =
const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind}
const_eval_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
const_eval_non_const_fmt_macro_call =
cannot call non-const formatting macro in {const_eval_const_context}s
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ pub(crate) struct DanglingPtrInFinal {
pub kind: InternKind,
}

#[derive(Diagnostic)]
#[diag(const_eval_nested_static_in_thread_local)]
pub(crate) struct NestedStaticInThreadLocal {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(const_eval_mutable_ptr_in_final)]
pub(crate) struct MutablePtrInFinal {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_const_eval/src/interpret/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_span::sym;

use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy};
use crate::const_eval;
use crate::errors::{DanglingPtrInFinal, MutablePtrInFinal};
use crate::errors::{DanglingPtrInFinal, MutablePtrInFinal, NestedStaticInThreadLocal};

pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine<
'mir,
Expand Down Expand Up @@ -108,6 +108,10 @@ fn intern_as_new_static<'tcx>(
);
tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());

if tcx.is_thread_local_static(static_id.into()) {
tcx.dcx().emit_err(NestedStaticInThreadLocal { span: tcx.def_span(static_id) });
}

// These do not inherit the codegen attrs of the parent static allocation, since
// it doesn't make sense for them to inherit their `#[no_mangle]` and `#[link_name = ..]`
// and the like.
Expand Down
28 changes: 9 additions & 19 deletions tests/ui/statics/nested_thread_local.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
// Check that nested statics in thread locals are
// duplicated per thread.
// Check that we forbid nested statics in `thread_local` statics.

#![feature(const_refs_to_cell)]
#![feature(thread_local)]

//@run-pass

#[thread_local]
static mut FOO: &mut u32 = &mut 42;

fn main() {
unsafe {
*FOO = 1;

let _ = std::thread::spawn(|| {
assert_eq!(*FOO, 42);
*FOO = 99;
})
.join();

assert_eq!(*FOO, 1);
}
}
static mut FOO: &u32 = {
//~^ ERROR: does not support implicit nested statics
// Prevent promotion (that would trigger on `&42` as an expression)
let x = 42;
&{ x }
};

fn main() {}
8 changes: 8 additions & 0 deletions tests/ui/statics/nested_thread_local.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
--> $DIR/nested_thread_local.rs:7:1
|
LL | static mut FOO: &u32 = {
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

0 comments on commit 64b75f7

Please sign in to comment.