]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Correctly emit warning on invalid attributes
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Mon, 23 Feb 2026 14:08:10 +0000 (15:08 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Fri, 20 Mar 2026 17:10:39 +0000 (18:10 +0100)
We were emitting warning even on attribute that were then removed by
the cfgstrip pass. We cannot move the cfg strip pass before the attribute
checking because we need to first emit malformed input error messages.
This means the attribute checking pass must know if an attribute input
may be removed later down the line.

gcc/rust/ChangeLog:

* ast/rust-ast.cc (MetaItemPathExpr::to_attribute): Remove cast to
literal.
(AttrInputMetaItemContainer::separate_cfg_attrs): Remove PathExpr
specific code.
* expand/rust-cfg-strip.cc (expand_cfg_attrs): Remove the whole
attribute if condition's result is false.
* util/rust-attributes.cc (AttributeChecker::visit): Remove specific
code section for meta item container. Do not check input if
configuration does not match condition.

gcc/testsuite/ChangeLog:

* rust/compile/attr_malformed_path.rs: Filter existing test to x86_64
exclusively, add two new tests that appear when visiting the resulting
expression.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/ast/rust-ast.cc
gcc/rust/expand/rust-cfg-strip.cc
gcc/rust/util/rust-attributes.cc
gcc/testsuite/rust/compile/attr_malformed_path.rs

index 228cacbe52ebea1ae1f2db109dbf232721cfed4c..d9a383675cf96aa1eda589d6ca0b14db2b9d64fe 100644 (file)
@@ -4200,10 +4200,8 @@ MetaListNameValueStr::to_attribute () const
 Attribute
 MetaItemPathExpr::to_attribute () const
 {
-  rust_assert (expr->is_literal ());
-  auto &lit = static_cast<LiteralExpr &> (*expr);
-  return Attribute (path, std::unique_ptr<AttrInputLiteral> (
-                           new AttrInputLiteral (lit)));
+  auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
+  return Attribute (path, std::move (input));
 }
 
 std::vector<Attribute>
@@ -4219,13 +4217,9 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const
 
   for (auto it = items.begin () + 1; it != items.end (); ++it)
     {
-      if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem
-         && static_cast<MetaItem &> (**it).get_item_kind ()
-              == MetaItem::ItemKind::PathExpr
-         && !static_cast<MetaItemPathExpr &> (**it).get_expr ().is_literal ())
-       continue;
+      auto &item = **it;
 
-      Attribute attr = (*it)->to_attribute ();
+      Attribute attr = item.to_attribute ();
       if (attr.is_empty ())
        {
          /* TODO should this be an error that causes us to chuck out
index 59cec98af6c15586ca4c2a64c81f0d52f9425463..2e6971e63f32e667d7b34817e9399fb414394170 100644 (file)
@@ -93,6 +93,9 @@ expand_cfg_attrs (AST::AttrVec &attrs)
 
          if (attr.check_cfg_predicate (session))
            {
+             // Key has been found we need to remove the conditional part of
+             // the attribute and insert the content back
+
              // split off cfg_attr
              AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
 
@@ -110,6 +113,12 @@ expand_cfg_attrs (AST::AttrVec &attrs)
               */
              i--;
            }
+         else
+           {
+             // Key has not been found, remove the whole attribute
+             attrs.erase (attrs.begin () + i);
+             i--;
+           }
 
          /* do something - if feature (first token in tree) is in fact enabled,
           * make tokens listed afterwards into attributes. i.e.: for
index bf2762f68daa784be95749910092749e6b4f0497..d246cc6721153764be5b50522f574d1db0a097c9 100644 (file)
@@ -553,34 +553,28 @@ check_lint_attribute (const AST::Attribute &attribute, const char *name)
 void
 AttributeChecker::visit (AST::Attribute &attribute)
 {
-  if (!attribute.empty_input ())
+  auto &session = Session::get_instance ();
+  if (attribute.get_path () == Values::Attributes::CFG_ATTR)
     {
-      const auto &attr_input = attribute.get_attr_input ();
-      auto type = attr_input.get_attr_input_type ();
-      if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
-       {
-         const auto &option = static_cast<const AST::DelimTokenTree &> (
-           attribute.get_attr_input ());
-         std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
-           option.parse_to_meta_item ());
-         AST::DefaultASTVisitor::visit (meta_item);
-       }
+      if (!attribute.is_parsed_to_meta_item ())
+       attribute.parse_attr_to_meta_item ();
+      if (!attribute.check_cfg_predicate (session))
+       return; // Do not emit errors for attribute that'll get stripped.
     }
 
-  auto result_opt = identify_builtin (attribute);
-
-  // This checker does not check non-builtin attributes
-  if (!result_opt.has_value ())
-    return;
-  auto result = result_opt.value ();
+  if (auto builtin = identify_builtin (attribute))
+    {
+      auto result = builtin.value ();
+      // TODO: Add checks here for each builtin attribute
+      // TODO: Have an enum of builtins as well, switching on strings is
+      // annoying and costly
+      if (result.name == Attrs::DOC)
+       check_doc_attribute (attribute);
+      else if (result.name == Attrs::DEPRECATED)
+       check_deprecated_attribute (attribute);
+    }
 
-  // TODO: Add checks here for each builtin attribute
-  // TODO: Have an enum of builtins as well, switching on strings is annoying
-  // and costly
-  if (result.name == Attrs::DOC)
-    check_doc_attribute (attribute);
-  else if (result.name == Attrs::DEPRECATED)
-    check_deprecated_attribute (attribute);
+  AST::DefaultASTVisitor::visit (attribute);
 }
 
 void
index 024a8363e12566c151f9eda31dfe480d2534f5c3..56ed4a4e9d2ff42dc87555ca20c798f0a37bb6c2 100644 (file)
@@ -3,4 +3,6 @@
 
 #[cfg_attr(target_arch = "x86_64", path = (target_arch = "x86",    path = "x86.rs"))]
 mod imp {}
-// { dg-error "malformed .path. attribute input" "" { target *-*-* } .-2 }
+// { dg-error "malformed .path. attribute input" "" { target { x86_64-*-* && { lp64 } } } .-2 }
+// { dg-error "cannot find value .target_arch. in this scope" "" { target { x86_64-*-* && { lp64 } } } .-3 }
+// { dg-error "cannot find value .path. in this scope" "" { target { x86_64-*-* && { lp64 } } } .-4 }