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 }
