diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-08-18 20:12:28 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-09-03 13:39:34 +0300 |
| commit | e88d4ca0e1bb7c3b0a446788ea0c010aaea65ffc (patch) | |
| tree | 31c42de603fd42f5737f49013166c2cf066c18fc | |
| parent | f3b41c18a8dfbcfec4b2a9e8d9e6a921189e3eea (diff) | |
| download | rust-e88d4ca0e1bb7c3b0a446788ea0c010aaea65ffc.tar.gz rust-e88d4ca0e1bb7c3b0a446788ea0c010aaea65ffc.zip | |
Make accesses to union fields unsafe
| -rw-r--r-- | src/librustc/middle/effect.rs | 24 | ||||
| -rw-r--r-- | src/test/compile-fail/union-unsafe.rs | 23 | ||||
| -rw-r--r-- | src/test/run-pass/union-basic.rs | 20 | ||||
| -rw-r--r-- | src/test/run-pass/union-pat-refutability.rs | 14 |
4 files changed, 63 insertions, 18 deletions
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 250ad80f5af..e52eba68da1 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -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>) { diff --git a/src/test/compile-fail/union-unsafe.rs b/src/test/compile-fail/union-unsafe.rs new file mode 100644 index 00000000000..762ac5d8751 --- /dev/null +++ b/src/test/compile-fail/union-unsafe.rs @@ -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 +} diff --git a/src/test/run-pass/union-basic.rs b/src/test/run-pass/union-basic.rs index dee86b232b4..afbfe5bf92b 100644 --- a/src/test/run-pass/union-basic.rs +++ b/src/test/run-pass/union-basic.rs @@ -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); + } } diff --git a/src/test/run-pass/union-pat-refutability.rs b/src/test/run-pass/union-pat-refutability.rs index 6b39eed7ac9..a57c1103a9b 100644 --- a/src/test/run-pass/union-pat-refutability.rs +++ b/src/test/run-pass/union-pat-refutability.rs @@ -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); + } } } } |
