From d6d2a7f0852da3f0dd0929c88abfa1d276553bf0 Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Wed, 1 Oct 2025 12:36:45 +0200 Subject: [PATCH 1/4] Emit an error on malformed path Path must be made of a single literal item, otherwise an error should be thrown. gcc/rust/ChangeLog: * util/rust-attributes.cc (AttributeChecker::check_attribute): Recurse within attr input for additional attribute checking. (AttributeChecker::visit): Remove empty definition in favor of default ast visitor definition. * util/rust-attributes.h: Remove now unused prototypes. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/util/rust-attributes.cc | 35 +++++++++++++++++++++++--------- gcc/rust/util/rust-attributes.h | 2 -- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index 716af3af699..cc16d9666a0 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -325,6 +325,20 @@ check_proc_macro_non_root (AST::AttrVec attributes, location_t loc) void AttributeChecker::check_attribute (const AST::Attribute &attribute) { + if (!attribute.empty_input ()) + { + 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 ( + attribute.get_attr_input ()); + std::unique_ptr meta_item ( + option.parse_to_meta_item ()); + AST::DefaultASTVisitor::visit (meta_item); + } + } + BuiltinAttrDefinition result; // This checker does not check non-builtin attributes @@ -353,10 +367,6 @@ void AttributeChecker::visit (AST::DelimTokenTree &) {} -void -AttributeChecker::visit (AST::AttrInputMetaItemContainer &) -{} - void AttributeChecker::visit (AST::IdentifierExpr &) {} @@ -420,8 +430,16 @@ AttributeChecker::visit (AST::MetaItemLitExpr &) {} void -AttributeChecker::visit (AST::MetaItemPathExpr &) -{} +AttributeChecker::visit (AST::MetaItemPathExpr &attribute) +{ + if (!attribute.get_expr ().is_literal ()) + { + rust_error_at (attribute.get_locus (), + "malformed % attribute input"); + rust_inform (attribute.get_locus (), + "must be of the form: %<#[path = \"file\"]%>"); + } +} void AttributeChecker::visit (AST::BorrowExpr &) @@ -647,6 +665,7 @@ AttributeChecker::visit (AST::TypeBoundWhereClauseItem &) void AttributeChecker::visit (AST::Module &module) { + check_attributes (module.get_outer_attrs ()); check_proc_macro_non_function (module.get_outer_attrs ()); for (auto &item : module.get_items ()) { @@ -861,10 +880,6 @@ void AttributeChecker::visit (AST::MetaItemPath &) {} -void -AttributeChecker::visit (AST::MetaItemSeq &) -{} - void AttributeChecker::visit (AST::MetaWord &) {} diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h index 22670991beb..0ad3c2b9284 100644 --- a/gcc/rust/util/rust-attributes.h +++ b/gcc/rust/util/rust-attributes.h @@ -112,7 +112,6 @@ class AttributeChecker : public AST::DefaultASTVisitor void visit (AST::Crate &crate) override; void visit (AST::Token &tok) override; void visit (AST::DelimTokenTree &delim_tok_tree) override; - void visit (AST::AttrInputMetaItemContainer &input) override; void visit (AST::IdentifierExpr &ident_expr) override; void visit (AST::Lifetime &lifetime) override; void visit (AST::LifetimeParam &lifetime_param) override; @@ -220,7 +219,6 @@ class AttributeChecker : public AST::DefaultASTVisitor void visit (AST::MacroRulesDefinition &rules_def) override; void visit (AST::MacroInvocation ¯o_invoc) override; void visit (AST::MetaItemPath &meta_item) override; - void visit (AST::MetaItemSeq &meta_item) override; void visit (AST::MetaWord &meta_item) override; void visit (AST::MetaNameValueStr &meta_item) override; void visit (AST::MetaListPaths &meta_item) override; From 6b23049118b87a26ca937154e7f45886d161528b Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Wed, 1 Oct 2025 16:24:18 +0200 Subject: [PATCH 2/4] Add override modifier gcc/rust/ChangeLog: * ast/rust-ast.h: Add missing override modifier. * ast/rust-path.h: Likewise. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/ast/rust-ast.h | 2 +- gcc/rust/ast/rust-path.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index f14136f445b..8a7e618b05c 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1777,7 +1777,7 @@ class TraitItem : public AssociatedItem return std::unique_ptr (clone_associated_item_impl ()); } - NodeId get_node_id () const { return node_id; } + NodeId get_node_id () const override { return node_id; } location_t get_locus () const override { return locus; } }; diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 88b5327c33c..be04882ed6a 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -1255,7 +1255,7 @@ class TypePath : public TypeNoBounds TraitBound *to_trait_bound (bool in_parens) const override; location_t get_locus () const override final { return locus; } - NodeId get_node_id () const { return node_id; } + NodeId get_node_id () const override { return node_id; } void mark_for_strip () override {} bool is_marked_for_strip () const override { return false; } From 1d80adb744b720cf2563192736b05741b0f7ff71 Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Wed, 1 Oct 2025 16:26:47 +0200 Subject: [PATCH 3/4] Force crash when retrieving meta item location We still don't know which location should be preferred over the other, this means that nobody should rely on this function's return value. gcc/rust/ChangeLog: * ast/rust-expr.h: Force crash when retrieving locus. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/ast/rust-expr.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 239b9511f67..3c36238c6ee 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -298,7 +298,11 @@ class MetaItemPathExpr : public MetaItem // we have no idea use which of them, just simply return UNKNOWN_LOCATION // now. // Maybe we will figure out when we really need the location in the future. - location_t get_locus () const override { return UNKNOWN_LOCATION; } + location_t get_locus () const override + { + rust_unreachable (); + return UNKNOWN_LOCATION; + } void accept_vis (ASTVisitor &vis) override; From 30610d7bd6167752150004a15f03231cf5293a83 Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Wed, 1 Oct 2025 16:35:37 +0200 Subject: [PATCH 4/4] Avoid malformed attribute conversion Add location for malformed attribute errors and avoid processing of malformed attributes. gcc/rust/ChangeLog: * ast/rust-ast.cc (AttrInputMetaItemContainer::separate_cfg_attrs): Avoid malformed attributes. * util/rust-attributes.cc (AttributeChecker::visit): Change location. gcc/testsuite/ChangeLog: * rust/compile/attr_malformed_path.rs: New test. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/ast/rust-ast.cc | 6 ++++++ gcc/rust/util/rust-attributes.cc | 4 ++-- gcc/testsuite/rust/compile/attr_malformed_path.rs | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/rust/compile/attr_malformed_path.rs diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 003a6edbc10..a4b256c9e67 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -4128,6 +4128,12 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const for (auto it = items.begin () + 1; it != items.end (); ++it) { + if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem + && static_cast (**it).get_item_kind () + == MetaItem::ItemKind::PathExpr + && !static_cast (**it).get_expr ().is_literal ()) + continue; + Attribute attr = (*it)->to_attribute (); if (attr.is_empty ()) { diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index cc16d9666a0..0059b72823a 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -434,9 +434,9 @@ AttributeChecker::visit (AST::MetaItemPathExpr &attribute) { if (!attribute.get_expr ().is_literal ()) { - rust_error_at (attribute.get_locus (), + rust_error_at (attribute.get_expr ().get_locus (), "malformed % attribute input"); - rust_inform (attribute.get_locus (), + rust_inform (attribute.get_expr ().get_locus (), "must be of the form: %<#[path = \"file\"]%>"); } } diff --git a/gcc/testsuite/rust/compile/attr_malformed_path.rs b/gcc/testsuite/rust/compile/attr_malformed_path.rs new file mode 100644 index 00000000000..2bccf37bd79 --- /dev/null +++ b/gcc/testsuite/rust/compile/attr_malformed_path.rs @@ -0,0 +1,3 @@ +#[cfg_attr(target_arch = "x86_64", path = (target_arch = "x86", path = "x86.rs"))] +mod imp {} +// { dg-error "malformed .path. attribute input" "" { target *-*-* } .-2 }