From: Lucas Ly Ba <[email protected]>

gcc/rust/ChangeLog:

        * ast/rust-ast.cc (Attribute::is_derive):
        Change string derive to its definition.
        * util/rust-attribute-values.h:
        Add attribute definition derive.
        * util/rust-attributes.cc (AttributeChecker::visit):
        Add method check_inner_attributes.
        (AttributeChecker::check_inner_attributes):
        Check if there is a bad inner attribute.
        * util/rust-attributes.h:
        Add method check_inner_attributes in .h.

gcc/testsuite/ChangeLog:

        * rust/compile/issue-4212.rs: New test.

Signed-off-by: Lucas Ly Ba <[email protected]>
---
 gcc/rust/ast/rust-ast.cc                 |  2 +-
 gcc/rust/util/rust-attribute-values.h    |  2 ++
 gcc/rust/util/rust-attributes.cc         | 12 ++++++++++++
 gcc/rust/util/rust-attributes.h          |  2 ++
 gcc/testsuite/rust/compile/issue-4212.rs |  5 +++++
 5 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4212.rs

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 4e81de85be4..337a338f9a3 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 () == "derive";
+  return has_attr_input () && get_path () == Values::Attributes::DERIVE;
 }
 
 /**
diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 0f35f56f798..a22664a1c48 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -49,6 +49,8 @@ public:
   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 e4d787794d4..9621100cc95 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -90,6 +90,8 @@ 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},
@@ -170,6 +172,7 @@ AttributeChecker::go (AST::Crate &crate)
 void
 AttributeChecker::visit (AST::Crate &crate)
 {
+  check_inner_attributes (crate.get_inner_attrs ());
   check_attributes (crate.get_inner_attrs ());
 
   for (auto &item : crate.items)
@@ -353,6 +356,15 @@ 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 0ad3c2b9284..b10a0806530 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -106,6 +106,8 @@ private:
   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
new file mode 100644
index 00000000000..e068e458c24
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4212.rs
@@ -0,0 +1,5 @@
+#![derive(PartialOrd, PartialEq)]
+// { dg-error "derive attribute cannot be used at crate level" "" { target 
*-*-* } .-1 }
+pub fn check_ge(a: i32, b: i32) -> bool {
+    a >= b
+}
-- 
2.50.1

Reply via email to