[gcc r15-1105] c++: Handle erroneous DECL_LOCAL_DECL_ALIAS in duplicate_decls [PR107575]

Simon Martin simartin@gcc.gnu.org
Fri Jun 7 18:41:54 GMT 2024


https://gcc.gnu.org/g:0ce138694a6b40708a80691fa4003f6af1defa49

commit r15-1105-g0ce138694a6b40708a80691fa4003f6af1defa49
Author: Simon Martin <simon@nasilyan.com>
Date:   Tue Jun 4 21:20:23 2024 +0200

    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.

Diff:
---
 gcc/cp/decl.cc                       | 11 +++++++----
 gcc/testsuite/g++.dg/parse/crash74.C | 11 +++++++++++
 2 files changed, 18 insertions(+), 4 deletions(-)

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 }


More information about the Gcc-cvs mailing list