Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make pointers to statics internal #68494

Merged
merged 1 commit into from
Jan 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions src/librustc_mir/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,28 +233,30 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
if let (local, []) = (&place.local, proj_base) {
let decl = &self.body.local_decls[*local];
if decl.internal {
// Internal locals are used in the `move_val_init` desugaring.
// We want to check unsafety against the source info of the
// desugaring, rather than the source info of the RHS.
self.source_info = self.body.local_decls[*local].source_info;
} else if let LocalInfo::StaticRef { def_id, .. } = decl.local_info {
if self.tcx.is_mutable_static(def_id) {
self.require_unsafe(
"use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing \
violations or data races will cause undefined behavior",
UnsafetyViolationKind::General,
);
return;
} else if self.tcx.is_foreign_item(def_id) {
self.require_unsafe(
"use of extern static",
"extern statics are not controlled by the Rust type system: \
invalid data, aliasing violations or data races will cause \
undefined behavior",
UnsafetyViolationKind::General,
);
return;
if let LocalInfo::StaticRef { def_id, .. } = decl.local_info {
if self.tcx.is_mutable_static(def_id) {
self.require_unsafe(
"use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing \
violations or data races will cause undefined behavior",
UnsafetyViolationKind::General,
);
return;
} else if self.tcx.is_foreign_item(def_id) {
self.require_unsafe(
"use of extern static",
"extern statics are not controlled by the Rust type system: \
invalid data, aliasing violations or data races will cause \
undefined behavior",
UnsafetyViolationKind::General,
);
return;
}
} else {
// Internal locals are used in the `move_val_init` desugaring.
// We want to check unsafety against the source info of the
// desugaring, rather than the source info of the RHS.
self.source_info = self.body.local_decls[*local].source_info;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir_build/build/expr/as_temp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
if let ExprKind::StaticRef { def_id, .. } = expr.kind {
let is_thread_local = this.hir.tcx().has_attr(def_id, sym::thread_local);
local_decl.internal = true;
local_decl.local_info = LocalInfo::StaticRef { def_id, is_thread_local };
}
this.local_decls.push(local_decl)
Expand Down
13 changes: 2 additions & 11 deletions src/librustc_typeck/check/generator_interior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,6 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
}

fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);

match &expr.kind {
ExprKind::Call(callee, args) => match &callee.kind {
ExprKind::Path(qpath) => {
Expand All @@ -249,20 +247,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
}
_ => intravisit::walk_expr(self, expr),
},
ExprKind::Path(qpath) => {
let res = self.fcx.tables.borrow().qpath_res(qpath, expr.hir_id);
if let Res::Def(DefKind::Static, def_id) = res {
// Statics are lowered to temporary references or
// pointers in MIR, so record that type.
let ptr_ty = self.fcx.tcx.static_ptr_ty(def_id);
self.record(ptr_ty, scope, Some(expr), expr.span);
}
}
_ => intravisit::walk_expr(self, expr),
}

self.expr_count += 1;

let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);

// If there are adjustments, then record the final type --
// this is the actual value that is being produced.
if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {
Expand Down
33 changes: 33 additions & 0 deletions src/test/ui/async-await/issues/issue-67611-static-mut-refs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// build-pass
// edition:2018

static mut A: [i32; 5] = [1, 2, 3, 4, 5];

fn is_send_sync<T: Send + Sync>(_: T) {}

async fn fun() {
let u = unsafe { A[async { 1 }.await] };
unsafe {
match A {
i if async { true }.await => (),
_ => (),
}
}
}

fn main() {
let index_block = async {
let u = unsafe { A[async { 1 }.await] };
};
let match_block = async {
unsafe {
match A {
i if async { true }.await => (),
_ => (),
}
}
};
is_send_sync(index_block);
is_send_sync(match_block);
is_send_sync(fun());
}
29 changes: 29 additions & 0 deletions src/test/ui/generator/static-mut-reference-across-yield.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// build-pass
#![feature(generators)]

static mut A: [i32; 5] = [1, 2, 3, 4, 5];

fn is_send_sync<T: Send + Sync>(_: T) {}

fn main() {
unsafe {
let gen_index = static || {
let u = A[{
yield;
1
}];
};
let gen_match = static || match A {
i if {
yield;
true
} =>
{
()
}
_ => (),
};
is_send_sync(gen_index);
is_send_sync(gen_match);
}
}