[gcc r17-3076] gccrs: Register global_allocator attribute

Arthur Cohen via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:662e6049df5e55d0a74f6b330ac95716aae870f5

commit r17-3076-g662e6049df5e55d0a74f6b330ac95716aae870f5
Author: Owen Avery <[email protected]>
Date:   Thu Jul 2 22:08:05 2026 -0400

    gccrs: Register global_allocator attribute
    
    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 <[email protected]>

Diff:
---
 .../errors/rust-builtin-attribute-checker.cc       | 63 +++++++---------------
 gcc/rust/util/rust-attribute-values.h              |  3 ++
 gcc/rust/util/rust-attributes.cc                   |  3 +-
 gcc/testsuite/rust/compile/global-allocator.rs     | 15 ++++++
 4 files changed, 39 insertions(+), 45 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-builtin-attribute-checker.cc b/gcc/rust/checks/errors/rust-builtin-attribute-checker.cc
index ba1bf6be1153..fef94f5eaca2 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 9c14df39b1cd..2b8853c8039d 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 08115d4653c5..1b65f7729fb0 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 000000000000..1433033c5da5
--- /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 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.