Skip to content

Commit 0aa7f4d

Browse files
committed
Make TLS accesses explicit in MIR
1 parent 0e9e408 commit 0aa7f4d

File tree

31 files changed

+157
-23
lines changed

31 files changed

+157
-23
lines changed

src/librustc_codegen_llvm/common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
259259
GlobalAlloc::Function(fn_instance) => self.get_fn_addr(fn_instance),
260260
GlobalAlloc::Static(def_id) => {
261261
assert!(self.tcx.is_static(def_id));
262+
assert!(!self.tcx.is_thread_local_static(def_id));
262263
self.get_static(def_id)
263264
}
264265
};

src/librustc_codegen_ssa/mir/rvalue.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
522522
let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
523523
(bx, operand)
524524
}
525+
mir::Rvalue::ThreadLocalRef(def_id) => {
526+
assert!(bx.cx().tcx().is_static(def_id));
527+
let static_ = bx.get_static(def_id);
528+
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id));
529+
let operand = OperandRef::from_immediate_or_packed_pair(&mut bx, static_, layout);
530+
(bx, operand)
531+
}
525532
mir::Rvalue::Use(ref operand) => {
526533
let operand = self.codegen_operand(&mut bx, operand);
527534
(bx, operand)
@@ -745,6 +752,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
745752
mir::Rvalue::UnaryOp(..) |
746753
mir::Rvalue::Discriminant(..) |
747754
mir::Rvalue::NullaryOp(..) |
755+
mir::Rvalue::ThreadLocalRef(_) |
748756
mir::Rvalue::Use(..) => // (*)
749757
true,
750758
mir::Rvalue::Repeat(..) |

src/librustc_middle/mir/interpret/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ pub enum UnsupportedOpInfo {
513513
//
514514
/// Encountered raw bytes where we needed a pointer.
515515
ReadBytesAsPointer,
516+
/// Accessing thread local statics
517+
ThreadLocalStatic(DefId),
516518
}
517519

518520
impl fmt::Display for UnsupportedOpInfo {
@@ -526,6 +528,7 @@ impl fmt::Display for UnsupportedOpInfo {
526528
NoMirFor(did) => write!(f, "no MIR body is available for {:?}", did),
527529
ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes",),
528530
ReadBytesAsPointer => write!(f, "unable to turn bytes into a pointer"),
531+
ThreadLocalStatic(did) => write!(f, "accessing thread local static {:?}", did),
529532
}
530533
}
531534
}

src/librustc_middle/mir/interpret/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
209209
fn_instance.encode(encoder)?;
210210
}
211211
GlobalAlloc::Static(did) => {
212+
assert!(!tcx.is_thread_local_static(did));
212213
// References to statics doesn't need to know about their allocations,
213214
// just about its `DefId`.
214215
AllocDiscriminant::Static.encode(encoder)?;

src/librustc_middle/mir/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2209,6 +2209,11 @@ pub enum Rvalue<'tcx> {
22092209
/// &x or &mut x
22102210
Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
22112211

2212+
/// Accessing a thread local static. This is inherently a runtime operation, even if llvm
2213+
/// treats it as an access to a static. This `Rvalue` yields a reference to the thread local
2214+
/// static.
2215+
ThreadLocalRef(DefId),
2216+
22122217
/// Create a raw pointer to the given place
22132218
/// Can be generated by raw address of expressions (`&raw const x`),
22142219
/// or when casting a reference to a raw pointer.
@@ -2348,6 +2353,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
23482353
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
23492354
Discriminant(ref place) => write!(fmt, "discriminant({:?})", place),
23502355
NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
2356+
ThreadLocalRef(did) => ty::tls::with(|tcx| {
2357+
let muta = tcx.static_mutability(did).unwrap().prefix_str();
2358+
write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did))
2359+
}),
23512360
Ref(region, borrow_kind, ref place) => {
23522361
let kind_str = match borrow_kind {
23532362
BorrowKind::Shared => "",
@@ -2501,7 +2510,10 @@ impl Constant<'tcx> {
25012510
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
25022511
match self.literal.val.try_to_scalar() {
25032512
Some(Scalar::Ptr(ptr)) => match tcx.global_alloc(ptr.alloc_id) {
2504-
GlobalAlloc::Static(def_id) => Some(def_id),
2513+
GlobalAlloc::Static(def_id) => {
2514+
assert!(!tcx.is_thread_local_static(def_id));
2515+
Some(def_id)
2516+
}
25052517
_ => None,
25062518
},
25072519
_ => None,

src/librustc_middle/mir/tcx.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ impl<'tcx> Rvalue<'tcx> {
152152
Rvalue::Repeat(ref operand, count) => {
153153
tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
154154
}
155+
Rvalue::ThreadLocalRef(did) => {
156+
if tcx.is_mutable_static(did) {
157+
tcx.mk_mut_ptr(tcx.type_of(did))
158+
} else {
159+
tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did))
160+
}
161+
}
155162
Rvalue::Ref(reg, bk, ref place) => {
156163
let place_ty = place.ty(local_decls, tcx).ty;
157164
tcx.mk_ref(reg, ty::TypeAndMut { ty: place_ty, mutbl: bk.to_mutbl_lossy() })

src/librustc_middle/mir/type_foldable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
173173
match *self {
174174
Use(ref op) => Use(op.fold_with(folder)),
175175
Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
176+
ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)),
176177
Ref(region, bk, ref place) => {
177178
Ref(region.fold_with(folder), bk, place.fold_with(folder))
178179
}
@@ -216,6 +217,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
216217
match *self {
217218
Use(ref op) => op.visit_with(visitor),
218219
Repeat(ref op, _) => op.visit_with(visitor),
220+
ThreadLocalRef(did) => did.visit_with(visitor),
219221
Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
220222
AddressOf(_, ref place) => place.visit_with(visitor),
221223
Len(ref place) => place.visit_with(visitor),

src/librustc_middle/mir/visit.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,8 @@ macro_rules! make_mir_visitor {
600600
self.visit_operand(value, location);
601601
}
602602

603+
Rvalue::ThreadLocalRef(_) => {}
604+
603605
Rvalue::Ref(r, bk, path) => {
604606
self.visit_region(r, location);
605607
let ctx = match bk {

src/librustc_mir/borrow_check/invalidation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
295295
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
296296
}
297297

298+
Rvalue::ThreadLocalRef(_) => {}
299+
298300
Rvalue::Use(ref operand)
299301
| Rvalue::Repeat(ref operand, _)
300302
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)

src/librustc_mir/borrow_check/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12901290
);
12911291
}
12921292

1293+
Rvalue::ThreadLocalRef(_) => {}
1294+
12931295
Rvalue::Use(ref operand)
12941296
| Rvalue::Repeat(ref operand, _)
12951297
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)

0 commit comments

Comments
 (0)