https://gcc.gnu.org/g:6d3f40bf10f5d4a8910110634d2c3ea795a32b16
commit r16-4757-g6d3f40bf10f5d4a8910110634d2c3ea795a32b16 Author: Owen Avery <[email protected]> Date: Tue Aug 5 16:44:02 2025 -0400 gccrs: Improve handling of AttrInputLiteral Also adjusts a few error messages to be more in line with rustc (and more amenable to extract_string_literal usage). gcc/rust/ChangeLog: * util/rust-attributes.cc (Attributes::extract_string_literal): New function definition. * util/rust-attributes.h (Attributes::extract_string_literal): New function declaration. * ast/rust-collect-lang-items.cc (get_lang_item_attr): Use extract_string_literal. * backend/rust-compile-base.cc: Include "rust-attributes.h". (HIRCompileBase::handle_link_section_attribute_on_fndecl): Use extract_string_literal. (HIRCompileBase::handle_must_use_attribute_on_fndecl): Likewise. * hir/rust-ast-lower-base.cc (ASTLoweringBase::handle_lang_item_attribute): Likewise. * rust-session-manager.cc (Session::handle_crate_name): Likewise. Signed-off-by: Owen Avery <[email protected]> Diff: --- gcc/rust/ast/rust-collect-lang-items.cc | 14 ++++++-------- gcc/rust/backend/rust-compile-base.cc | 24 +++++++++--------------- gcc/rust/hir/rust-ast-lower-base.cc | 7 ++++--- gcc/rust/rust-session-manager.cc | 17 ++++++++--------- gcc/rust/util/rust-attributes.cc | 25 +++++++++++++++++++++++++ gcc/rust/util/rust-attributes.h | 2 ++ 6 files changed, 54 insertions(+), 35 deletions(-) diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc index 306c6f747e2b..1efe26f8dfd3 100644 --- a/gcc/rust/ast/rust-collect-lang-items.cc +++ b/gcc/rust/ast/rust-collect-lang-items.cc @@ -43,18 +43,16 @@ get_lang_item_attr (const T &maybe_lang_item) continue; } - bool is_lang_item = str_path == Values::Attributes::LANG - && attr.has_attr_input () - && attr.get_attr_input ().get_attr_input_type () - == AST::AttrInput::AttrInputType::LITERAL; + bool is_lang_item = str_path == Values::Attributes::LANG; if (is_lang_item) { - auto &literal - = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ()); - const auto &lang_item_type_str = literal.get_literal ().as_string (); + auto lang_item_type_str + = Analysis::Attributes::extract_string_literal (attr); - return LangItem::Parse (lang_item_type_str); + rust_assert (lang_item_type_str.has_value ()); + + return LangItem::Parse (*lang_item_type_str); } } diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 73c34b269b7e..d1db58e32844 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -32,6 +32,7 @@ #include "rust-type-util.h" #include "rust-compile-implitem.h" #include "rust-attribute-values.h" +#include "rust-attributes.h" #include "rust-immutable-name-resolution-context.h" #include "fold-const.h" @@ -251,25 +252,21 @@ void HIRCompileBase::handle_link_section_attribute_on_fndecl ( tree fndecl, const AST::Attribute &attr) { - if (!attr.has_attr_input ()) + auto msg_str = Analysis::Attributes::extract_string_literal (attr); + + if (!msg_str.has_value ()) { rust_error_at (attr.get_locus (), - "%<link_section%> expects exactly one argment"); + "malformed %<link_section%> attribute input"); return; } - rust_assert (attr.get_attr_input ().get_attr_input_type () - == AST::AttrInput::AttrInputType::LITERAL); - - auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ()); - const auto &msg_str = literal.get_literal ().as_string (); - if (decl_section_name (fndecl)) { rust_warning_at (attr.get_locus (), 0, "section name redefined"); } - set_decl_section_name (fndecl, msg_str.c_str ()); + set_decl_section_name (fndecl, msg_str->c_str ()); } void @@ -416,13 +413,10 @@ HIRCompileBase::handle_must_use_attribute_on_fndecl (tree fndecl, if (attr.has_attr_input ()) { - rust_assert (attr.get_attr_input ().get_attr_input_type () - == AST::AttrInput::AttrInputType::LITERAL); + auto msg_str = Analysis::Attributes::extract_string_literal (attr); + rust_assert (msg_str.has_value ()); - auto &literal - = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ()); - const auto &msg_str = literal.get_literal ().as_string (); - tree message = build_string (msg_str.size (), msg_str.c_str ()); + tree message = build_string (msg_str->size (), msg_str->c_str ()); value = tree_cons (nodiscard, message, NULL_TREE); } diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index 7cbef42b5e4f..9445658300cd 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -850,9 +850,10 @@ void ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item, const AST::Attribute &attr) { - auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ()); - const auto &lang_item_type_str = literal.get_literal ().as_string (); - auto lang_item_type = LangItem::Parse (lang_item_type_str); + auto lang_item_type_str = Analysis::Attributes::extract_string_literal (attr); + rust_assert (lang_item_type_str.has_value ()); + + auto lang_item_type = LangItem::Parse (*lang_item_type_str); if (lang_item_type) mappings.insert_lang_item (*lang_item_type, diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 17f9c06040d0..c88f46757535 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -422,32 +422,31 @@ Session::handle_crate_name (const char *filename, { if (attr.get_path () != "crate_name") continue; - if (!attr.has_attr_input ()) + + auto msg_str = Analysis::Attributes::extract_string_literal (attr); + if (!msg_str.has_value ()) { rust_error_at (attr.get_locus (), - "%<crate_name%> accepts one argument"); + "malformed %<crate_name%> attribute input"); continue; } - auto &literal - = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ()); - const auto &msg_str = literal.get_literal ().as_string (); - if (!validate_crate_name (msg_str, error)) + if (!validate_crate_name (*msg_str, error)) { error.locus = attr.get_locus (); error.emit (); continue; } - if (options.crate_name_set_manually && (options.crate_name != msg_str)) + if (options.crate_name_set_manually && (options.crate_name != *msg_str)) { rust_error_at (attr.get_locus (), "%<-frust-crate-name%> and %<#[crate_name]%> are " "required to match, but %qs does not match %qs", - options.crate_name.c_str (), msg_str.c_str ()); + options.crate_name.c_str (), msg_str->c_str ()); } crate_name_found = true; - options.set_crate_name (msg_str); + options.set_crate_name (*msg_str); } options.crate_name_set_manually |= crate_name_found; diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index c846c2d5c33c..265391827e42 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -38,6 +38,31 @@ Attributes::is_known (const std::string &attribute_path) return !lookup.is_error (); } +tl::optional<std::string> +Attributes::extract_string_literal (const AST::Attribute &attr) +{ + if (!attr.has_attr_input ()) + return tl::nullopt; + + auto &attr_input = attr.get_attr_input (); + + if (attr_input.get_attr_input_type () + != AST::AttrInput::AttrInputType::LITERAL) + return tl::nullopt; + + auto &literal_expr + = static_cast<AST::AttrInputLiteral &> (attr_input).get_literal (); + + auto lit_type = literal_expr.get_lit_type (); + + // TODO: bring escape sequence handling out of lexing? + if (lit_type != AST::Literal::LitType::STRING + && lit_type != AST::Literal::LitType::RAW_STRING) + return tl::nullopt; + + return literal_expr.as_string (); +} + using Attrs = Values::Attributes; // https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248 diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h index db8fe234778c..da3b0cd25810 100644 --- a/gcc/rust/util/rust-attributes.h +++ b/gcc/rust/util/rust-attributes.h @@ -29,6 +29,8 @@ class Attributes { public: static bool is_known (const std::string &attribute_path); + static tl::optional<std::string> + extract_string_literal (const AST::Attribute &attr); }; enum CompilerPass
