public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] unsafe: Forbid use of certain static values outside of unsafe contexts
@ 2022-07-28 7:53 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-07-28 7:53 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:f4e4c2444fc10f7952fc4dffceb9e3a7e85ed973
commit f4e4c2444fc10f7952fc4dffceb9e3a7e85ed973
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date: Mon Jul 25 13:30:27 2022 +0200
unsafe: Forbid use of certain static values outside of unsafe contexts
Using a mutable static or an extern static requires an unsafe function
or block
Diff:
---
gcc/rust/checks/errors/rust-unsafe-checker.cc | 78 +++++++++++++++++++++++++--
gcc/rust/checks/errors/rust-unsafe-checker.h | 9 ++++
gcc/testsuite/rust/compile/unsafe1.rs | 14 +++++
gcc/testsuite/rust/compile/unsafe2.rs | 16 ++++++
gcc/testsuite/rust/compile/unsafe3.rs | 10 ++++
5 files changed, 123 insertions(+), 4 deletions(-)
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index def3cc11b7a..d234179f2fa 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -25,7 +25,10 @@
namespace Rust {
namespace HIR {
-UnsafeChecker::UnsafeChecker () : context (*Resolver::TypeCheckContext::get ())
+UnsafeChecker::UnsafeChecker ()
+ : context (*Resolver::TypeCheckContext::get ()),
+ resolver (*Resolver::Resolver::get ()),
+ mappings (*Analysis::Mappings::get ())
{}
void
@@ -35,6 +38,47 @@ UnsafeChecker::go (HIR::Crate &crate)
item->accept_vis (*this);
}
+static void
+check_static_mut (HIR::Item *maybe_static, Location locus)
+{
+ if (maybe_static->get_hir_kind () == Node::BaseKind::VIS_ITEM)
+ {
+ auto item = static_cast<Item *> (maybe_static);
+ if (item->get_item_kind () == Item::ItemKind::Static)
+ {
+ auto static_item = static_cast<StaticItem *> (item);
+ if (static_item->is_mut ())
+ rust_error_at (
+ locus, "use of mutable static requires unsafe function or block");
+ }
+ }
+}
+
+static void
+check_extern_static (HIR::ExternalItem *maybe_static, Location locus)
+{
+ if (maybe_static->get_extern_kind () == ExternalItem::ExternKind::Static)
+ rust_error_at (locus,
+ "use of extern static requires unsafe function or block");
+}
+
+void
+UnsafeChecker::check_use_of_static (HirId node_id, Location locus)
+{
+ if (is_unsafe_context ())
+ return;
+
+ auto maybe_static_mut = mappings.lookup_hir_item (node_id);
+ auto maybe_extern_static = mappings.lookup_hir_extern_item (node_id);
+
+ if (maybe_static_mut)
+ check_static_mut (maybe_static_mut, locus);
+
+ if (maybe_extern_static)
+ check_extern_static (static_cast<ExternalItem *> (maybe_extern_static),
+ locus);
+}
+
void
UnsafeChecker::push_unsafe (HirId id)
{
@@ -60,7 +104,18 @@ UnsafeChecker::is_unsafe_context ()
void
UnsafeChecker::visit (IdentifierExpr &ident_expr)
-{}
+{
+ NodeId ast_node_id = ident_expr.get_mappings ().get_nodeid ();
+ NodeId ref_node_id;
+ HirId definition_id;
+
+ if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ return;
+
+ rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
+
+ check_use_of_static (definition_id, ident_expr.get_locus ());
+}
void
UnsafeChecker::visit (Lifetime &lifetime)
@@ -72,7 +127,18 @@ UnsafeChecker::visit (LifetimeParam &lifetime_param)
void
UnsafeChecker::visit (PathInExpression &path)
-{}
+{
+ NodeId ast_node_id = path.get_mappings ().get_nodeid ();
+ NodeId ref_node_id;
+ HirId definition_id;
+
+ if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ return;
+
+ rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
+
+ check_use_of_static (definition_id, path.get_locus ());
+}
void
UnsafeChecker::visit (TypePathSegment &segment)
@@ -253,7 +319,11 @@ UnsafeChecker::visit (StructExprStructBase &expr)
void
UnsafeChecker::visit (CallExpr &expr)
-{}
+{
+ if (expr.has_params ())
+ for (auto &arg : expr.get_arguments ())
+ arg->accept_vis (*this);
+}
void
UnsafeChecker::visit (MethodCallExpr &expr)
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 3c817073993..38b9019e3b7 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -20,6 +20,7 @@
#define RUST_UNSAFE_CHECKER_H
#include "rust-hir-visitor.h"
+#include "rust-name-resolver.h"
#include "rust-hir-type-check.h"
namespace Rust {
@@ -51,7 +52,15 @@ private:
*/
bool is_unsafe_context ();
+ /**
+ * Check if a mutable static or external static item is used outside of an
+ * unsafe context
+ */
+ void check_use_of_static (HirId node_id, Location locus);
+
Resolver::TypeCheckContext &context;
+ Resolver::Resolver resolver;
+ Analysis::Mappings mappings;
virtual void visit (IdentifierExpr &ident_expr) override;
virtual void visit (Lifetime &lifetime) override;
diff --git a/gcc/testsuite/rust/compile/unsafe1.rs b/gcc/testsuite/rust/compile/unsafe1.rs
new file mode 100644
index 00000000000..9cd3f6b4bf2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe1.rs
@@ -0,0 +1,14 @@
+fn foo(_a: &i32) {}
+fn bar(_a: i32) {}
+
+static mut a: i32 = 15;
+
+fn main() {
+ foo(&a); // { dg-error "use of mutable static" }
+ bar(a); // { dg-error "use of mutable static" }
+
+ unsafe {
+ foo(&a);
+ bar(a);
+ }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe2.rs b/gcc/testsuite/rust/compile/unsafe2.rs
new file mode 100644
index 00000000000..e03e4bc59f4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe2.rs
@@ -0,0 +1,16 @@
+fn foo(_a: &i32) {}
+fn bar(_a: i32) {}
+
+mod inner {
+ pub static mut a: i32 = 15;
+}
+
+fn main() {
+ foo(&inner::a); // { dg-error "use of mutable static" }
+ bar(inner::a); // { dg-error "use of mutable static" }
+
+ unsafe {
+ foo(&inner::a);
+ bar(inner::a);
+ }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe3.rs b/gcc/testsuite/rust/compile/unsafe3.rs
new file mode 100644
index 00000000000..56aec76008a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe3.rs
@@ -0,0 +1,10 @@
+extern "C" {
+ static VALUE: char;
+}
+
+fn main() {
+ let _ = VALUE; // { dg-error "use of extern static" }
+ unsafe {
+ let _ = VALUE;
+ }
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-07-28 7:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-28 7:53 [gcc/devel/rust/master] unsafe: Forbid use of certain static values outside of unsafe contexts Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).