From a1a398268005f937a1010b6d54daef2d32a1af8d Mon Sep 17 00:00:00 2001 From: Lucas Ly Ba Date: Mon, 3 Nov 2025 16:28:56 +0000 Subject: [PATCH] gccrs: make invalid inner attributes show error gcc/rust/ChangeLog: * ast/rust-ast.cc (Attribute::is_derive): Change is_derive method with its valid path. * util/rust-attribute-values.h: Delete redudant derive attribute. * util/rust-attributes.cc (AttributeChecker::check_inner_attribute): Helper method for check_inner_attributes (AttributeChecker::check_inner_attributes): Implement method for errors check. * util/rust-attributes.h: Add methods above in header. gcc/testsuite/ChangeLog: * rust/compile/issue-4212.rs: * rust/compile/issue-4219.rs: New test. Signed-off-by: Lucas Ly Ba --- gcc/rust/ast/rust-ast.cc | 2 +- gcc/rust/util/rust-attribute-values.h | 2 -- gcc/rust/util/rust-attributes.cc | 43 ++++++++++++++---------- gcc/rust/util/rust-attributes.h | 8 +++-- gcc/testsuite/rust/compile/issue-4212.rs | 2 +- gcc/testsuite/rust/compile/issue-4219.rs | 5 +++ 6 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/rust/compile/issue-4219.rs diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 337a338f9a3..36d4c598980 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -248,7 +248,7 @@ Attribute::as_string () const bool Attribute::is_derive () const { - return has_attr_input () && get_path () == Values::Attributes::DERIVE; + return has_attr_input () && get_path () == Values::Attributes::DERIVE_ATTR; } /** diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h index a22664a1c48..0f35f56f798 100644 --- a/gcc/rust/util/rust-attribute-values.h +++ b/gcc/rust/util/rust-attribute-values.h @@ -49,8 +49,6 @@ class Attributes static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive"; static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute"; - static constexpr auto &DERIVE = "derive"; - static constexpr auto &TARGET_FEATURE = "target_feature"; // From now on, these are reserved by the compiler and gated through // #![feature(rustc_attrs)] diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index 9621100cc95..70f26e7ce36 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -90,8 +90,6 @@ static const BuiltinAttrDefinition __definitions[] {Attrs::PROC_MACRO, EXPANSION}, {Attrs::PROC_MACRO_DERIVE, EXPANSION}, {Attrs::PROC_MACRO_ATTRIBUTE, EXPANSION}, - - {Attrs::DERIVE, EXPANSION}, // FIXME: This is not implemented yet, see // https://github.com/Rust-GCC/gccrs/issues/1475 {Attrs::TARGET_FEATURE, CODE_GENERATION}, @@ -101,7 +99,6 @@ static const BuiltinAttrDefinition __definitions[] {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION}, {Attrs::STABLE, STATIC_ANALYSIS}, {Attrs::UNSTABLE, STATIC_ANALYSIS}, - // assuming we keep these for static analysis {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION}, {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS}, @@ -114,23 +111,22 @@ static const BuiltinAttrDefinition __definitions[] {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK}, {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK}, {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK}, - {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION}, - // TODO: be careful about calling functions marked with this? {Attrs::RUSTC_ARGS_REQUIRED_CONST, CODE_GENERATION}, - {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}, - {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS}, {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS}, - {Attrs::FUNDAMENTAL, TYPE_CHECK}, {Attrs::NON_EXHAUSTIVE, TYPE_CHECK}, {Attrs::RUSTFMT, EXTERNAL}, - {Attrs::TEST, CODE_GENERATION}}; +static const std::set __outer_attributes + = {Attrs::INLINE, Attrs::DERIVE_ATTR, Attrs::ALLOW_INTERNAL_UNSTABLE, + Attrs::LANG, Attrs::REPR, Attrs::PATH, + Attrs::TARGET_FEATURE, Attrs::TEST}; + BuiltinAttributeMappings * BuiltinAttributeMappings::get () { @@ -326,6 +322,26 @@ check_proc_macro_non_root (AST::AttrVec attributes, location_t loc) } } +void +AttributeChecker::check_inner_attribute (const AST::Attribute &attribute) +{ + BuiltinAttrDefinition result; + + if (!is_builtin (attribute, result)) + return; + + if (__outer_attributes.find (result.name) != __outer_attributes.end ()) + rust_error_at (attribute.get_locus (), + "attribute cannot be used at crate level"); +} + +void +AttributeChecker::check_inner_attributes (const AST::AttrVec &attributes) +{ + for (auto &attr : attributes) + check_inner_attribute (attr); +} + void AttributeChecker::check_attribute (const AST::Attribute &attribute) { @@ -356,15 +372,6 @@ AttributeChecker::check_attribute (const AST::Attribute &attribute) check_doc_attribute (attribute); } -void -AttributeChecker::check_inner_attributes (const AST::AttrVec &attributes) -{ - for (auto &attr : attributes) - if (attr.is_derive ()) - rust_error_at (attr.get_locus (), - "derive attribute cannot be used at crate level"); -} - void AttributeChecker::check_attributes (const AST::AttrVec &attributes) { diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h index b10a0806530..f4a2d389c3d 100644 --- a/gcc/rust/util/rust-attributes.h +++ b/gcc/rust/util/rust-attributes.h @@ -102,12 +102,14 @@ class AttributeChecker : public AST::DefaultASTVisitor private: using AST::DefaultASTVisitor::visit; + + /* Check the validity of an inner attribute */ + void check_inner_attribute (const AST::Attribute &attribute); + /* Check the validy of all inner attributes */ + void check_inner_attributes (const AST::AttrVec &attributes); /* Check the validity of a given attribute */ void check_attribute (const AST::Attribute &attribute); - /* Check the validity of all given attributes */ - - void check_inner_attributes (const AST::AttrVec &attributes); void check_attributes (const AST::AttrVec &attributes); // rust-ast.h diff --git a/gcc/testsuite/rust/compile/issue-4212.rs b/gcc/testsuite/rust/compile/issue-4212.rs index e068e458c24..e7bf113d7aa 100644 --- a/gcc/testsuite/rust/compile/issue-4212.rs +++ b/gcc/testsuite/rust/compile/issue-4212.rs @@ -1,5 +1,5 @@ #![derive(PartialOrd, PartialEq)] -// { dg-error "derive attribute cannot be used at crate level" "" { target *-*-* } .-1 } +// { dg-error "attribute cannot be used at crate level" "" { target *-*-* } .-1 } pub fn check_ge(a: i32, b: i32) -> bool { a >= b } diff --git a/gcc/testsuite/rust/compile/issue-4219.rs b/gcc/testsuite/rust/compile/issue-4219.rs new file mode 100644 index 00000000000..d6e70e9a726 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4219.rs @@ -0,0 +1,5 @@ +#![inline] +// { dg-error "attribute cannot be used at crate level" "" { target *-*-* } .-1 } +pub fn check_ge(a: i32, b: i32) -> bool { + a >= b +}