]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Handle erroneous DECL_LOCAL_DECL_ALIAS in duplicate_decls [PR107575]
authorSimon Martin <simon@nasilyan.com>
Tue, 4 Jun 2024 19:20:23 +0000 (21:20 +0200)
committerSimon Martin <simon@nasilyan.com>
Fri, 7 Jun 2024 18:40:16 +0000 (20:40 +0200)
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
gcc/testsuite/g++.dg/parse/crash74.C [new file with mode: 0644]

index d481e1ec074bc94bb7d2e8d3d6e0ee4b620dd051..03deb1493a43bd5295fd14270a0f69d435e807da 100644 (file)
@@ -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 (file)
index 0000000..a7ba509
--- /dev/null
@@ -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 }