diff mbox series

c++: Handle erroneous DECL_LOCAL_DECL_ALIAS in duplicate_decls [PR107575]

Message ID 0102018fe7759751-88e2bb17-ead4-4cf0-a199-fa6231f73b49-000000@eu-west-1.amazonses.com
State New
Headers show
Series c++: Handle erroneous DECL_LOCAL_DECL_ALIAS in duplicate_decls [PR107575] | expand

Commit Message

Simon Martin June 5, 2024, 8:13 a.m. UTC
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

Comments

Simon Martin June 5, 2024, 8:25 a.m. UTC | #1
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 <simon@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 }
Jakub Jelinek June 5, 2024, 8:34 a.m. UTC | #2
On Wed, Jun 05, 2024 at 08:13:14AM +0000, Simon Martin wrote:
> --- 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);

Formatting nit, = should be on the next line, not at the end of a line.
See https://gcc.gnu.org/codingconventions.html and https://gcc.gnu.org/codingconventions.html

	Jakub
Simon Martin June 5, 2024, 9:20 a.m. UTC | #3
On 5 Jun 2024, at 10:34, Jakub Jelinek wrote:

> On Wed, Jun 05, 2024 at 08:13:14AM +0000, Simon Martin wrote:
>> --- 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);
>
> Formatting nit, = should be on the next line, not at the end of a 
> line.
> See https://gcc.gnu.org/codingconventions.html and 
> https://gcc.gnu.org/codingconventions.html
Indeed, thanks. This is fixed in the attached updated patch.

Simon
>
> 	Jakub
From e75602d3ce998307749e5022d989b564a6d19703 Mon Sep 17 00:00:00 2001
From: Simon Martin <simon@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 }
Jason Merrill June 7, 2024, 5:32 p.m. UTC | #4
On 6/5/24 05:20, Simon Martin wrote:
> On 5 Jun 2024, at 10:34, Jakub Jelinek wrote:
> 
>> On Wed, Jun 05, 2024 at 08:13:14AM +0000, Simon Martin wrote:
>>> --- 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);
>>
>> Formatting nit, = should be on the next line, not at the end of a
>> line.
>> See https://gcc.gnu.org/codingconventions.html and
>> https://gcc.gnu.org/codingconventions.html
> Indeed, thanks. This is fixed in the attached updated patch.

OK.
diff mbox series

Patch

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) =
+		(*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 }