From: Owen Avery <[email protected]>

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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/2c930e694e32886076ec2230789f52756ee4a997

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4680

 .../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 ba1bf6be1..fef94f5ea 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 9c14df39b..2b8853c80 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 08115d465..1b65f7729 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 000000000..1433033c5
--- /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 }

base-commit: 76fc766f34824f3d4695dbc805a9bf58e19788be
-- 
2.54.0

Reply via email to