Skip to content

Commit 786575e

Browse files
committed
expand: Add error check if derive has wrong item
The DeriveVisitor previously dispatched calls to specific handlers (like DeriveClone) without validating the input item type. This caused internal compiler errors (ICEs) when users attempted to derive traits on invalid items like functions or traits, as the handlers assumed the input was a struct, enum, or union. This patch adds a validation predicate to the DeriveVisitor to reject invalid items gracefully with a diagnostic error before dispatching. Fixes #3875 gcc/rust/ChangeLog: * expand/rust-derive.h: Add validate_item prototype. * expand/rust-derive.cc (DeriveVisitor::derive): Use visitor validation. (DeriveVisitor::validate_item): New function to check item kind. gcc/testsuite/ChangeLog: * rust/compile/derive-on-invalid-item.rs: New test. Signed-off-by: Jayant Chauhan <[email protected]>
1 parent c35ffdb commit 786575e

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

gcc/rust/expand/rust-derive.cc

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,8 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
4040
{
4141
auto loc = attr.get_locus ();
4242

43-
using Kind = AST::Item::Kind;
44-
auto item_kind = item.get_item_kind ();
45-
if (item_kind != Kind::Enum && item_kind != Kind::Struct
46-
&& item_kind != Kind::Union)
43+
DeriveVisitor visitor (loc);
44+
if (!visitor.validate_item (item))
4745
{
4846
rust_error_at (loc,
4947
"derive may only be applied to structs, enums and unions");
@@ -159,5 +157,18 @@ DeriveVisitor::setup_impl_generics (
159157
return ImplGenerics{std::move (self_type_path), std::move (impl_generics)};
160158
}
161159

160+
bool
161+
DeriveVisitor::validate_item (const Item &item)
162+
{
163+
using Kind = AST::Item::Kind;
164+
auto item_kind = item.get_item_kind ();
165+
166+
if (item_kind == Kind::Enum || item_kind == Kind::Struct
167+
|| item_kind == Kind::Union)
168+
return true;
169+
170+
return false;
171+
}
172+
162173
} // namespace AST
163174
} // namespace Rust

gcc/rust/expand/rust-derive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class DeriveVisitor : public AST::ASTVisitor
7171
= tl::nullopt) const;
7272

7373
private:
74+
bool validate_item (const AST::Item &item);
7475
// the 4 "allowed" visitors, which a derive-visitor can specify and override
7576
virtual void visit_struct (StructStruct &struct_item) = 0;
7677
virtual void visit_tuple (TupleStruct &tuple_item) = 0;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// { dg-options "-w" }
2+
3+
#[derive(Clone)] // { dg-error "derive may only be applied to structs, enums and unions" }
4+
fn foo() {}
5+
6+
#[derive(Debug)] // { dg-error "derive may only be applied to structs, enums and unions" }
7+
trait Bar {}
8+
9+
#[derive(Copy)] // { dg-error "derive may only be applied to structs, enums and unions" }
10+
impl Bar for i32 {}
11+
12+
fn main() {}

0 commit comments

Comments
 (0)