Hi, There was a formatting error, corrected in the updated attached patch :-/
On 5 Jun 2024, at 10:13, Simon Martin wrote: > We currently ICE upon the following because we don't properly handle > local > functions with an error_mark_node as DECL_LOCAL_DECL_ALIAS in > duplicate_decls. > > === cut here === > void f (void) { > virtual int f (void) const; > virtual int f (void); > } > === cut here === > > This patch fixes this by checking for error_mark_node. > > Successfully tested on x86_64-pc-linux-gnu. > > PR c++/107575 > > gcc/cp/ChangeLog: > > * decl.cc (duplicate_decls): Check for error_mark_node > DECL_LOCAL_DECL_ALIAS. > > gcc/testsuite/ChangeLog: > > * g++.dg/parse/crash74.C: New test. > > --- > gcc/cp/decl.cc | 11 +++++++---- > gcc/testsuite/g++.dg/parse/crash74.C | 11 +++++++++++ > 2 files changed, 18 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/parse/crash74.C > > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index d481e1ec074..2ae46143d70 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -2792,10 +2792,13 @@ duplicate_decls (tree newdecl, tree olddecl, > bool hiding, bool was_hidden) > retrofit_lang_decl (newdecl); > tree alias = DECL_LOCAL_DECL_ALIAS (newdecl) > = DECL_LOCAL_DECL_ALIAS (olddecl); > - DECL_ATTRIBUTES (alias) > - = (*targetm.merge_decl_attributes) (alias, newdecl); > - if (TREE_CODE (newdecl) == FUNCTION_DECL) > - merge_attribute_bits (newdecl, alias); > + if (alias != error_mark_node) > + { > + DECL_ATTRIBUTES (alias) = The = sign should have been on the next line; this is the case in the updated patch. > + (*targetm.merge_decl_attributes) (alias, newdecl); > + if (TREE_CODE (newdecl) == FUNCTION_DECL) > + merge_attribute_bits (newdecl, alias); > + } > } > } > > diff --git a/gcc/testsuite/g++.dg/parse/crash74.C > b/gcc/testsuite/g++.dg/parse/crash74.C > new file mode 100644 > index 00000000000..a7ba5094be6 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/parse/crash74.C > @@ -0,0 +1,11 @@ > +// PR c++/107575 > + > +void f (void) { > + virtual int f (void) const; // { dg-line line_4 } > + virtual int f (void); // { dg-line line_5 } > +} > + > +// { dg-error "outside class declaration" {} { target *-*-* } line_4 > } > +// { dg-error "cannot have cv-qualifier" {} { target *-*-* } line_4 } > +// { dg-error "ambiguating new declaration of" {} { target *-*-* } > line_4 } > +// { dg-error "outside class declaration" {} { target *-*-* } line_5 > } > -- > 2.44.0
From e75602d3ce998307749e5022d989b564a6d19703 Mon Sep 17 00:00:00 2001 From: Simon Martin <si...@nasilyan.com> Date: Tue, 4 Jun 2024 21:20:23 +0200 Subject: [PATCH] c++: Handle erroneous DECL_LOCAL_DECL_ALIAS in duplicate_decls [PR107575] We currently ICE upon the following because we don't properly handle local functions with an error_mark_node as DECL_LOCAL_DECL_ALIAS in duplicate_decls. === cut here === void f (void) { virtual int f (void) const; virtual int f (void); } === cut here === This patch fixes this by checking for error_mark_node. Successfully tested on x86_64-pc-linux-gnu. PR c++/107575 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Check for error_mark_node DECL_LOCAL_DECL_ALIAS. gcc/testsuite/ChangeLog: * g++.dg/parse/crash74.C: New test. --- gcc/cp/decl.cc | 11 +++++++---- gcc/testsuite/g++.dg/parse/crash74.C | 11 +++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/crash74.C diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index d481e1ec074..03deb1493a4 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -2792,10 +2792,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) retrofit_lang_decl (newdecl); tree alias = DECL_LOCAL_DECL_ALIAS (newdecl) = DECL_LOCAL_DECL_ALIAS (olddecl); - DECL_ATTRIBUTES (alias) - = (*targetm.merge_decl_attributes) (alias, newdecl); - if (TREE_CODE (newdecl) == FUNCTION_DECL) - merge_attribute_bits (newdecl, alias); + if (alias != error_mark_node) + { + DECL_ATTRIBUTES (alias) + = (*targetm.merge_decl_attributes) (alias, newdecl); + if (TREE_CODE (newdecl) == FUNCTION_DECL) + merge_attribute_bits (newdecl, alias); + } } } diff --git a/gcc/testsuite/g++.dg/parse/crash74.C b/gcc/testsuite/g++.dg/parse/crash74.C new file mode 100644 index 00000000000..a7ba5094be6 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash74.C @@ -0,0 +1,11 @@ +// PR c++/107575 + +void f (void) { + virtual int f (void) const; // { dg-line line_4 } + virtual int f (void); // { dg-line line_5 } +} + +// { dg-error "outside class declaration" {} { target *-*-* } line_4 } +// { dg-error "cannot have cv-qualifier" {} { target *-*-* } line_4 } +// { dg-error "ambiguating new declaration of" {} { target *-*-* } line_4 } +// { dg-error "outside class declaration" {} { target *-*-* } line_5 } -- 2.44.0