diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-07-27 14:25:44 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-07-27 14:29:14 +0200 |
commit | 961468ed824a7b49f10ed597ba9dcc98177125ca (patch) | |
tree | 9a6292e682c843b6ee7c3f65f23e6f74fd6c0dca /gcc | |
parent | 6b14b560bc25465f2e8465c087ecd9684fb5fb65 (diff) | |
download | gcc-961468ed824a7b49f10ed597ba9dcc98177125ca.zip gcc-961468ed824a7b49f10ed597ba9dcc98177125ca.tar.gz gcc-961468ed824a7b49f10ed597ba9dcc98177125ca.tar.bz2 |
unsafe: Handle multi unsafe contexts by using stack
Co-authored-by: philberty <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/checks/errors/rust-unsafe-checker.cc | 37 | ||||
-rw-r--r-- | gcc/rust/checks/errors/rust-unsafe-checker.h | 21 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/unsafe4.rs | 9 |
3 files changed, 60 insertions, 7 deletions
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index d79254c..def3cc1 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -36,6 +36,29 @@ UnsafeChecker::go (HIR::Crate &crate) } void +UnsafeChecker::push_unsafe (HirId id) +{ + unsafe_contexts.emplace_back (id); +} + +HirId +UnsafeChecker::pop_unsafe () +{ + rust_assert (!unsafe_contexts.empty ()); + + auto last = unsafe_contexts.back (); + unsafe_contexts.pop_back (); + + return last; +} + +bool +UnsafeChecker::is_unsafe_context () +{ + return !unsafe_contexts.empty (); +} + +void UnsafeChecker::visit (IdentifierExpr &ident_expr) {} @@ -94,7 +117,7 @@ UnsafeChecker::visit (DereferenceExpr &expr) rust_assert (context.lookup_type (to_deref, &to_deref_type)); if (to_deref_type->get_kind () == TyTy::TypeKind::POINTER - && !in_unsafe_context) + && !is_unsafe_context ()) rust_error_at (expr.get_locus (), "dereference of raw pointer requires " "unsafe function or block"); } @@ -320,11 +343,11 @@ UnsafeChecker::visit (ReturnExpr &expr) void UnsafeChecker::visit (UnsafeBlockExpr &expr) { - in_unsafe_context = true; + push_unsafe (expr.get_mappings ().get_hirid ()); expr.get_block_expr ()->accept_vis (*this); - in_unsafe_context = false; + pop_unsafe (); } void @@ -485,11 +508,15 @@ UnsafeChecker::visit (UseDeclaration &use_decl) void UnsafeChecker::visit (Function &function) { - in_unsafe_context = function.get_qualifiers ().is_unsafe (); + auto is_unsafe_fn = function.get_qualifiers ().is_unsafe (); + + if (is_unsafe_fn) + push_unsafe (function.get_mappings ().get_hirid ()); function.get_definition ()->accept_vis (*this); - in_unsafe_context = false; + if (is_unsafe_fn) + pop_unsafe (); } void diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h index de122cb..3c81707 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.h +++ b/gcc/rust/checks/errors/rust-unsafe-checker.h @@ -32,8 +32,24 @@ public: void go (HIR::Crate &crate); private: - /* Are we currently in an unsafe function or block ? */ - bool in_unsafe_context; + /* Stack of unsafe contexts */ + std::vector<HirId> unsafe_contexts; + + /** + * Add an unsafe context to the stack. To call when entering unsafe blocks + */ + void push_unsafe (HirId id); + + /** + * Remove an unsafe context from the stack. Call this when exiting unsafe + * blocks + */ + HirId pop_unsafe (); + + /** + * Are we currently in an unsafe context or not + */ + bool is_unsafe_context (); Resolver::TypeCheckContext &context; @@ -170,6 +186,7 @@ private: virtual void visit (InferredType &type) override; virtual void visit (BareFunctionType &type) override; }; + } // namespace HIR } // namespace Rust diff --git a/gcc/testsuite/rust/compile/unsafe4.rs b/gcc/testsuite/rust/compile/unsafe4.rs index 06cdb4a..7d1356b 100644 --- a/gcc/testsuite/rust/compile/unsafe4.rs +++ b/gcc/testsuite/rust/compile/unsafe4.rs @@ -18,3 +18,12 @@ fn baz() -> i32 { *p_a // { dg-error "dereference of raw pointer" } } + +unsafe fn qux() -> i32 { + let a = 15; + let p_a = &a as *const i32; + + unsafe {} + + *p_a +} |