Make accesses to union fields unsafe
This commit is contained in:
parent
f3b41c18a8
commit
e88d4ca0e1
4 changed files with 63 additions and 18 deletions
|
|
@ -13,15 +13,14 @@
|
|||
use self::RootUnsafeContext::*;
|
||||
|
||||
use dep_graph::DepNode;
|
||||
use hir::def::Def;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::MethodCall;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
use hir;
|
||||
use hir::intravisit;
|
||||
use hir::intravisit::{FnKind, Visitor};
|
||||
use hir::{self, PatKind};
|
||||
use hir::def::Def;
|
||||
use hir::intravisit::{self, FnKind, Visitor};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct UnsafeContext {
|
||||
|
|
@ -178,11 +177,28 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
self.require_unsafe(expr.span, "use of mutable static");
|
||||
}
|
||||
}
|
||||
hir::ExprField(ref base_expr, field) => {
|
||||
if let ty::TyUnion(..) = self.tcx.expr_ty_adjusted(base_expr).sty {
|
||||
self.require_unsafe(field.span, "access to union field");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
intravisit::walk_expr(self, expr);
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &hir::Pat) {
|
||||
if let PatKind::Struct(_, ref fields, _) = pat.node {
|
||||
if let ty::TyUnion(..) = self.tcx.pat_ty(pat).sty {
|
||||
for field in fields {
|
||||
self.require_unsafe(field.span, "matching on union field");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intravisit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
|
|
|
|||
23
src/test/compile-fail/union-unsafe.rs
Normal file
23
src/test/compile-fail/union-unsafe.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
union U {
|
||||
a: u8
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let u = U { a: 10 }; // OK
|
||||
let a = u.a; //~ ERROR access to union field requires unsafe function or block
|
||||
let U { a } = u; //~ ERROR matching on union field requires unsafe function or block
|
||||
if let U { a: 11 } = u {} //~ ERROR matching on union field requires unsafe function or block
|
||||
let U { .. } = u; // OK
|
||||
}
|
||||
|
|
@ -42,14 +42,18 @@ fn main() {
|
|||
assert_eq!(align_of::<Y>(), 2);
|
||||
|
||||
let u = U { a: 10 };
|
||||
assert_eq!(u.a, 10);
|
||||
let U { a } = u;
|
||||
assert_eq!(a, 10);
|
||||
unsafe {
|
||||
assert_eq!(u.a, 10);
|
||||
let U { a } = u;
|
||||
assert_eq!(a, 10);
|
||||
}
|
||||
|
||||
let mut w: W = unsafe { zeroed() };
|
||||
assert_eq!(w.a, 0);
|
||||
assert_eq!(w.b, 0);
|
||||
// w.a = 1;
|
||||
// assert_eq!(w.a, 0);
|
||||
// assert_eq!(w.b, 0);
|
||||
unsafe {
|
||||
assert_eq!(w.a, 0);
|
||||
assert_eq!(w.b, 0);
|
||||
// w.a = 1;
|
||||
// assert_eq!(w.a, 0);
|
||||
// assert_eq!(w.b, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,12 +41,14 @@ union W {
|
|||
}
|
||||
|
||||
fn refut(w: W) {
|
||||
match w {
|
||||
W { a: 10 } => {
|
||||
panic!();
|
||||
}
|
||||
W { b } => {
|
||||
assert_eq!(b, 11);
|
||||
unsafe {
|
||||
match w {
|
||||
W { a: 10 } => {
|
||||
panic!();
|
||||
}
|
||||
W { b } => {
|
||||
assert_eq!(b, 11);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue