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 }

Reply via email to