[COMMITTED 18/77] gccrs: Register global_allocator attribute

arthur.cohen@embecosm.com arthur.cohen@embecosm.com
Fri Aug 7 12:39:09 GMT 2026


From: Owen Avery <powerboat9.gamer@gmail.com>

This allows gccrs to recognize the global_allocator attribute and
perform some sanity checks on its usage, but does not implement proper
handling for the attribute.

gcc/rust/ChangeLog:

	* checks/errors/rust-builtin-attribute-checker.cc (no_mangle):
	Remove function.
	(rustc_std_internal_symbol): Likewise.
	(rustc_allocator): Likewise.
	(rustc_allocator_nounwind): Likewise.
	(expect_no_input): New function.
	(attribute_checking_handlers): Use expect_no_input, new entry
	for GLOBAL_ALLOCATOR.
	(check_valid_attribute_for_item): Verify that GLOBAL_ALLOCATOR
	attributes only appear on static items.
	* util/rust-attribute-values.h (Attributes::GLOBAL_ALLOCATOR):
	New static constexpr member variable.
	* util/rust-attributes.cc (__definitions): New entry for
	GLOBAL_ALLOCATOR.

gcc/testsuite/ChangeLog:

	* rust/compile/global-allocator.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
---
 .../errors/rust-builtin-attribute-checker.cc  | 63 ++++++-------------
 gcc/rust/util/rust-attribute-values.h         |  3 +
 gcc/rust/util/rust-attributes.cc              |  3 +-
 .../rust/compile/global-allocator.rs          | 15 +++++
 4 files changed, 39 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/global-allocator.rs

diff --git a/gcc/rust/checks/errors/rust-builtin-attribute-checker.cc b/gcc/rust/checks/errors/rust-builtin-attribute-checker.cc
index ba1bf6be115..fef94f5eaca 100644
--- a/gcc/rust/checks/errors/rust-builtin-attribute-checker.cc
+++ b/gcc/rust/checks/errors/rust-builtin-attribute-checker.cc
@@ -348,49 +348,15 @@ target_feature (const AST::Attribute &attribute)
 }
 
 void
-no_mangle (const AST::Attribute &attribute)
+expect_no_input (const AST::Attribute &attribute)
 {
   if (attribute.has_attr_input ())
     {
-      rust_error_at (attribute.get_locus (), ErrorCode::E0754,
-		     "malformed %<no_mangle%> attribute input");
-      rust_inform (attribute.get_locus (),
-		   "must be of the form: %<#[no_mangle]%>");
-    }
-}
-void
-rustc_std_internal_symbol (const AST::Attribute &attribute)
-{
-  if (attribute.has_attr_input ())
-    {
-      rust_error_at (attribute.get_locus (),
-		     "malformed %<rustc_std_internal_symbol%> attribute input");
-      rust_inform (attribute.get_locus (),
-		   "must be of the form: %<#[rustc_std_internal_symbol]%>");
-    }
-}
-
-void
-rustc_allocator (const AST::Attribute &attribute)
-{
-  if (attribute.has_attr_input ())
-    {
-      rust_error_at (attribute.get_locus (),
-		     "malformed %<rustc_allocator%> attribute input");
-      rust_inform (attribute.get_locus (),
-		   "must be of the form: %<#[rustc_allocator]%>");
-    }
-}
-
-void
-rustc_allocator_nounwind (const AST::Attribute &attribute)
-{
-  if (attribute.has_attr_input ())
-    {
-      rust_error_at (attribute.get_locus (),
-		     "malformed %<rustc_allocator_nounwind%> attribute input");
-      rust_inform (attribute.get_locus (),
-		   "must be of the form: %<#[rustc_allocator_nounwind]%>");
+      std::string attr_name = attribute.get_path ().as_string ();
+      rust_error_at (attribute.get_locus (), "malformed %<%s%> attribute input",
+		     attr_name.c_str ());
+      rust_inform (attribute.get_locus (), "must be of the form: %<#[%s]%>",
+		   attr_name.c_str ());
     }
 }
 
@@ -402,7 +368,7 @@ const std::unordered_map<std::string, std::function<void (AST::Attribute &)>>
     {Attrs::DEPRECATED, handlers::deprecated},
     {Attrs::LINK_SECTION, handlers::link_section},
     {Attrs::EXPORT_NAME, handlers::export_name},
-    {Attrs::NO_MANGLE, handlers::no_mangle},
+    {Attrs::NO_MANGLE, handlers::expect_no_input},
     {Attrs::ALLOW, handlers::lint},
     {Attrs::DENY, handlers::lint},
     {Attrs::WARN, handlers::lint},
@@ -412,9 +378,10 @@ const std::unordered_map<std::string, std::function<void (AST::Attribute &)>>
     {Attrs::PROC_MACRO, handlers::proc_macro},
     {Attrs::PROC_MACRO_ATTRIBUTE, handlers::proc_macro},
     {Attrs::TARGET_FEATURE, handlers::target_feature},
-    {Attrs::RUSTC_STD_INTERNAL_SYMBOL, handlers::rustc_std_internal_symbol},
-    {Attrs::RUSTC_ALLOCATOR, handlers::rustc_allocator},
-    {Attrs::RUSTC_ALLOCATOR_NOUNWIND, handlers::rustc_allocator_nounwind},
+    {Attrs::RUSTC_STD_INTERNAL_SYMBOL, handlers::expect_no_input},
+    {Attrs::RUSTC_ALLOCATOR, handlers::expect_no_input},
+    {Attrs::RUSTC_ALLOCATOR_NOUNWIND, handlers::expect_no_input},
+    {Attrs::GLOBAL_ALLOCATOR, handlers::expect_no_input},
 };
 
 tl::optional<std::function<void (AST::Attribute &)>>
@@ -468,6 +435,14 @@ check_valid_attribute_for_item (const AST::Attribute &attr,
 		     "to structs, enums and unions",
 		     attr.get_path ().as_string ().c_str ());
     }
+  else if (attr.get_path () == Values::Attributes::GLOBAL_ALLOCATOR
+	   && item.get_item_kind () != AST::Item::Kind::StaticItem)
+    {
+      rust_error_at (attr.get_locus (),
+		     "the %<#[%s]%> attribute may only be applied "
+		     "to static items",
+		     attr.get_path ().as_string ().c_str ());
+    }
 }
 
 BuiltinAttributeChecker::BuiltinAttributeChecker () {}
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index 9c14df39b1c..2b8853c8039 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -61,6 +61,9 @@ public:
 
   static constexpr auto &TARGET_FEATURE = "target_feature";
   static constexpr auto &FEATURE = "feature";
+
+  static constexpr auto &GLOBAL_ALLOCATOR = "global_allocator";
+
   // From now on, these are reserved by the compiler and gated through
   // #![feature(rustc_attrs)]
   static constexpr auto &RUSTC_DEPRECATED = "rustc_deprecated";
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 08115d4653c..1b65f7729fb 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -96,7 +96,8 @@ static const BuiltinAttrDefinition __definitions[]
      {Attrs::RUSTFMT, EXTERNAL},
      {Attrs::TEST, CODE_GENERATION},
      {Attrs::RUSTC_ALLOCATOR, CODE_GENERATION},
-     {Attrs::RUSTC_ALLOCATOR_NOUNWIND, CODE_GENERATION}};
+     {Attrs::RUSTC_ALLOCATOR_NOUNWIND, CODE_GENERATION},
+     {Attrs::GLOBAL_ALLOCATOR, CODE_GENERATION}};
 
 static const std::set<std::string> __outer_attributes
   = {Attrs::INLINE,
diff --git a/gcc/testsuite/rust/compile/global-allocator.rs b/gcc/testsuite/rust/compile/global-allocator.rs
new file mode 100644
index 00000000000..1433033c5da
--- /dev/null
+++ b/gcc/testsuite/rust/compile/global-allocator.rs
@@ -0,0 +1,15 @@
+#![feature(no_core)]
+#![no_core]
+
+// TODO: there should be a check for X: GlobalAlloc
+// TODO: also, should this attribute be available with no_core?
+#[global_allocator]
+static A: u32 = 0;
+
+#[global_allocator()]
+static B: u32 = 0;
+// { dg-error "malformed .global_allocator. attribute" "" { target *-*-* } .-2 }
+
+#[global_allocator]
+const C: u32 = 0;
+// { dg-error "only be applied to static" "" { target *-*-* } .-2 }
-- 
2.50.1



More information about the Gcc-rust mailing list