From: Pierre-Emmanuel Patry <[email protected]>

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 <[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/12215f93093bbee9c140cb4ec74ebd32bc00673b

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

 gcc/rust/ast/rust-ast.cc                      | 14 ++-----
 gcc/rust/expand/rust-cfg-strip.cc             |  9 ++++
 gcc/rust/util/rust-attributes.cc              | 42 ++++++++-----------
 .../rust/compile/attr_malformed_path.rs       |  4 +-
 4 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 228cacbe5..d9a383675 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -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
diff --git a/gcc/rust/expand/rust-cfg-strip.cc 
b/gcc/rust/expand/rust-cfg-strip.cc
index 59cec98af..2e6971e63 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -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
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index bf2762f68..d246cc672 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -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
diff --git a/gcc/testsuite/rust/compile/attr_malformed_path.rs 
b/gcc/testsuite/rust/compile/attr_malformed_path.rs
index 024a8363e..56ed4a4e9 100644
--- a/gcc/testsuite/rust/compile/attr_malformed_path.rs
+++ b/gcc/testsuite/rust/compile/attr_malformed_path.rs
@@ -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 }
-- 
2.53.0

Reply via email to