From: Mason Pike Date: Thu, 25 Dec 2025 21:15:57 +0000 (+0100) Subject: gccrs: proc error on invalid type X-Git-Tag: basepoints/gcc-17~1017 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c59664fb828563cd0af7356c0902440ed05f13f0;p=thirdparty%2Fgcc.git gccrs: proc error on invalid type fixes Rust-GCC/gccrs#4235 gcc/rust/ChangeLog: * util/rust-attributes.cc: add new function to validate that an attribute is assigned to a valid item type gcc/testsuite/ChangeLog: * rust/compile/issue-4232.rs: update expected error to include the specific illegal attribute Signed-off-by: Mason Pike --- diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index 4a0422d3fba..6c0fa0ea070 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -369,6 +369,45 @@ check_deprecated_attribute (const AST::Attribute &attribute) } } +/** + * Emit an error when an attribute is attached + * to an incompatable item type. e.g.: + * + * #[cold] + * struct A(u8, u8); + * + * Note that "#[derive]" is handled + * explicitly in rust-derive.cc + */ +static void +check_valid_attribute_for_item (const AST::AttrVec &attributes, + const AST::Item &item) +{ + for (auto &attr : attributes) + { + if (item.get_item_kind () != AST::Item::Kind::Function + && (attr.get_path () == Values::Attributes::TARGET_FEATURE + || attr.get_path () == Values::Attributes::COLD + || attr.get_path () == Values::Attributes::INLINE)) + { + rust_error_at ( + attr.get_locus (), + "the %<#[%s]%> attribute may only be applied to functions", + attr.get_path ().as_string ().c_str ()); + } + else if (attr.get_path () == Values::Attributes::REPR + && item.get_item_kind () == AST::Item::Kind::Enum + && item.get_item_kind () == AST::Item::Kind::Union + && item.get_item_kind () == AST::Item::Kind::Struct) + { + rust_error_at (attr.get_locus (), + "the %<#[%s]%> attribute may only be applied " + "to structs, enums and unions", + attr.get_path ().as_string ().c_str ()); + } + } +} + static bool is_proc_macro_type (const AST::Attribute &attribute) { @@ -809,6 +848,7 @@ AttributeChecker::visit (AST::TypeBoundWhereClauseItem &) void AttributeChecker::visit (AST::Module &module) { + check_valid_attribute_for_item (module.get_outer_attrs (), module); check_attributes (module.get_outer_attrs ()); check_proc_macro_non_function (module.get_outer_attrs ()); for (auto &item : module.get_items ()) @@ -821,6 +861,7 @@ AttributeChecker::visit (AST::Module &module) void AttributeChecker::visit (AST::ExternCrate &crate) { + check_valid_attribute_for_item (crate.get_outer_attrs (), crate); check_proc_macro_non_function (crate.get_outer_attrs ()); } @@ -839,6 +880,7 @@ AttributeChecker::visit (AST::UseTreeRebind &) void AttributeChecker::visit (AST::UseDeclaration &declaration) { + check_valid_attribute_for_item (declaration.get_outer_attrs (), declaration); check_proc_macro_non_function (declaration.get_outer_attrs ()); } @@ -861,6 +903,7 @@ check_no_mangle_function (const AST::Attribute &attribute, void AttributeChecker::visit (AST::Function &fun) { + check_valid_attribute_for_item (fun.get_outer_attrs (), fun); auto check_crate_type = [] (const char *name, AST::Attribute &attribute) { if (!Session::get_instance ().options.is_proc_macro ()) rust_error_at (attribute.get_locus (), @@ -943,12 +986,6 @@ AttributeChecker::visit (AST::Function &fun) { check_link_section_attribute (attribute); } - else if (result.name == Attrs::REPR) - { - rust_error_at ( - attribute.get_locus (), - "attribute should be applied to a struct, enum, or union"); - } } if (fun.has_body ()) @@ -958,12 +995,14 @@ AttributeChecker::visit (AST::Function &fun) void AttributeChecker::visit (AST::TypeAlias &alias) { + check_valid_attribute_for_item (alias.get_outer_attrs (), alias); check_proc_macro_non_function (alias.get_outer_attrs ()); } void AttributeChecker::visit (AST::StructStruct &struct_item) { + check_valid_attribute_for_item (struct_item.get_outer_attrs (), struct_item); check_attributes (struct_item.get_outer_attrs ()); check_proc_macro_non_function (struct_item.get_outer_attrs ()); } @@ -971,6 +1010,7 @@ AttributeChecker::visit (AST::StructStruct &struct_item) void AttributeChecker::visit (AST::TupleStruct &tuplestruct) { + check_valid_attribute_for_item (tuplestruct.get_outer_attrs (), tuplestruct); check_proc_macro_non_function (tuplestruct.get_outer_attrs ()); } @@ -993,24 +1033,28 @@ AttributeChecker::visit (AST::EnumItemDiscriminant &) void AttributeChecker::visit (AST::Enum &enumeration) { + check_valid_attribute_for_item (enumeration.get_outer_attrs (), enumeration); check_proc_macro_non_function (enumeration.get_outer_attrs ()); } void AttributeChecker::visit (AST::Union &u) { + check_valid_attribute_for_item (u.get_outer_attrs (), u); check_proc_macro_non_function (u.get_outer_attrs ()); } void AttributeChecker::visit (AST::ConstantItem &item) { + check_valid_attribute_for_item (item.get_outer_attrs (), item); check_proc_macro_non_function (item.get_outer_attrs ()); } void AttributeChecker::visit (AST::StaticItem &item) { + check_valid_attribute_for_item (item.get_outer_attrs (), item); check_proc_macro_non_function (item.get_outer_attrs ()); BuiltinAttrDefinition result; @@ -1037,6 +1081,7 @@ AttributeChecker::visit (AST::TraitItemType &) void AttributeChecker::visit (AST::Trait &trait) { + check_valid_attribute_for_item (trait.get_outer_attrs (), trait); check_proc_macro_non_function (trait.get_outer_attrs ()); check_attributes (trait.get_outer_attrs ()); } @@ -1044,6 +1089,7 @@ AttributeChecker::visit (AST::Trait &trait) void AttributeChecker::visit (AST::InherentImpl &impl) { + check_valid_attribute_for_item (impl.get_outer_attrs (), impl); check_proc_macro_non_function (impl.get_outer_attrs ()); AST::DefaultASTVisitor::visit (impl); } @@ -1051,6 +1097,7 @@ AttributeChecker::visit (AST::InherentImpl &impl) void AttributeChecker::visit (AST::TraitImpl &impl) { + check_valid_attribute_for_item (impl.get_outer_attrs (), impl); check_proc_macro_non_function (impl.get_outer_attrs ()); AST::DefaultASTVisitor::visit (impl); } @@ -1066,6 +1113,7 @@ AttributeChecker::visit (AST::ExternalStaticItem &) void AttributeChecker::visit (AST::ExternBlock &block) { + check_valid_attribute_for_item (block.get_outer_attrs (), block); check_proc_macro_non_function (block.get_outer_attrs ()); } diff --git a/gcc/testsuite/rust/compile/issue-4232.rs b/gcc/testsuite/rust/compile/issue-4232.rs index fa12538808d..96a896665b2 100644 --- a/gcc/testsuite/rust/compile/issue-4232.rs +++ b/gcc/testsuite/rust/compile/issue-4232.rs @@ -1,3 +1,3 @@ // { dg-options "-w" } -#[repr(C)] // { dg-error "attribute should be applied to a struct, enum, or union" } -fn a() {} \ No newline at end of file +#[repr(C)] // { dg-error "the ...repr.. attribute may only be applied to structs, enums and unions" } +fn a() {} diff --git a/gcc/testsuite/rust/compile/issue-4235.rs b/gcc/testsuite/rust/compile/issue-4235.rs new file mode 100644 index 00000000000..5febf1f4d8a --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4235.rs @@ -0,0 +1,2 @@ +#[target_feature(enable = "sse")] // { dg-error "the ...target_feature.. attribute may only be applied to functions" } +struct _Test {}