diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-07-26 15:44:18 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-07-27 22:24:49 +0200 |
commit | f532ae5aa37c8555dd6a99d8502436509db7930f (patch) | |
tree | 98895c16750e4816f6420658fcc4758767783607 /gcc | |
parent | 50ca4b2ba0028945fd1a0aefec739ea99f77e908 (diff) | |
download | gcc-f532ae5aa37c8555dd6a99d8502436509db7930f.zip gcc-f532ae5aa37c8555dd6a99d8502436509db7930f.tar.gz gcc-f532ae5aa37c8555dd6a99d8502436509db7930f.tar.bz2 |
unsafe: Add checks for union field accesses
Co-authored-by: philberty <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/checks/errors/rust-unsafe-checker.cc | 20 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/unsafe9.rs | 10 |
2 files changed, 27 insertions, 3 deletions
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index def3cc1..99f59ac 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -262,10 +262,24 @@ UnsafeChecker::visit (MethodCallExpr &expr) void UnsafeChecker::visit (FieldAccessExpr &expr) { - // FIXME: If the receiver is an union, we need to be in an unsafe context to - // access it. Make sure to check. - expr.get_receiver_expr ()->accept_vis (*this); + + if (is_unsafe_context ()) + return; + + TyTy::BaseType *receiver_ty; + auto ok = context.lookup_type ( + expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver_ty); + rust_assert (ok); + + if (receiver_ty->get_kind () == TyTy::TypeKind::ADT) + { + auto maybe_union = static_cast<TyTy::ADTType *> (receiver_ty); + if (maybe_union->is_union ()) + rust_error_at ( + expr.get_locus (), + "access to union field requires unsafe function or block"); + } } void diff --git a/gcc/testsuite/rust/compile/unsafe9.rs b/gcc/testsuite/rust/compile/unsafe9.rs new file mode 100644 index 0000000..fb46c8f --- /dev/null +++ b/gcc/testsuite/rust/compile/unsafe9.rs @@ -0,0 +1,10 @@ +union U { + a: i32, + b: f32, + c: u8, +} + +fn main() { + let u = U { a: 14 }; + let _ = u.a; // { dg-error "access to union" } +} |