diff mbox series

c++: Fix crash during NRV optimization with invalid input [PR117099]

Message ID 0102019296d5f0d6-503071f0-4f6b-4ed0-80b6-9cbf5ebf7a6c-000000@eu-west-1.amazonses.com
State New
Headers show
Series c++: Fix crash during NRV optimization with invalid input [PR117099] | expand

Commit Message

Simon Martin Oct. 16, 2024, 7:37 p.m. UTC
We ICE upon the following invalid code because we end up calling
finalize_nrv_r with a RETURN_EXPR with no operand.

=== cut here ===
struct X {
  ~X();
};
X test(bool b) {
  {
    X x;
    return x;
  }
  if (!(b)) return;
}
=== cut here ===

This patch fixes this by simply returning error_mark_node when detecting
a void return in a function returning non-void.

Successfully tested on x86_64-pc-linux-gnu.

	PR c++/117099

gcc/cp/ChangeLog:

	* typeck.cc (check_return_expr): Return error_mark_node upon
	void return for function returning non-void.

gcc/testsuite/ChangeLog:

	* g++.dg/parse/crash77.C: New test.

---
 gcc/cp/typeck.cc                     |  1 +
 gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
 2 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C

Comments

Sam James Oct. 16, 2024, 8:06 p.m. UTC | #1
Simon Martin <simon@nasilyan.com> writes:

> We ICE upon the following invalid code because we end up calling
> finalize_nrv_r with a RETURN_EXPR with no operand.
> 
> === cut here ===
> struct X {
>   ~X();
> };
> X test(bool b) {
>   {
>     X x;
>     return x;
>   }
>   if (!(b)) return;
> }
> === cut here ===
> 
> This patch fixes this by simply returning error_mark_node when detecting
> a void return in a function returning non-void.
> 
> Successfully tested on x86_64-pc-linux-gnu.
> 
> 	PR c++/117099
> 
> gcc/cp/ChangeLog:
> 
> 	* typeck.cc (check_return_expr): Return error_mark_node upon
> 	void return for function returning non-void.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/parse/crash77.C: New test.
> 
> ---
>  gcc/cp/typeck.cc                     |  1 +
>  gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
>  2 files changed, 15 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C
> 
> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
> index 71d879abef1..22a6ec9a185 100644
> --- a/gcc/cp/typeck.cc
> +++ b/gcc/cp/typeck.cc
> @@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling)
>  	 RETURN_EXPR to avoid control reaches end of non-void function
>  	 warnings in tree-cfg.cc.  */
>        *no_warning = true;
> +      return error_mark_node;
>      }
>    /* Check for a return statement with a value in a function that
>       isn't supposed to return a value.  */
> diff --git a/gcc/testsuite/g++.dg/parse/crash77.C b/gcc/testsuite/g++.dg/parse/crash77.C
> new file mode 100644
> index 00000000000..d3f0ae6a877
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/parse/crash77.C
> @@ -0,0 +1,14 @@
> +// PR c++/117099
> +// { dg-compile }

dg-do compile

> +
> +struct X {
> +  ~X();
> +};
> +
> +X test(bool b) {
> +  {
> +    X x;
> +    return x;
> +  } 
> +  if (!(b)) return; // { dg-error "return-statement with no value" }
> +}
> -- 
> 2.44.0
> 

BTW, the line-endings on this seem a bit odd. Did you use git-send-email?
Simon Martin Oct. 17, 2024, 8:38 a.m. UTC | #2
Hi Sam,

On 16 Oct 2024, at 22:06, Sam James wrote:

> Simon Martin <simon@nasilyan.com> writes:
>
>> We ICE upon the following invalid code because we end up calling
>> finalize_nrv_r with a RETURN_EXPR with no operand.
>>
>> === cut here ===
>> struct X {
>>   ~X();
>> };
>> X test(bool b) {
>>   {
>>     X x;
>>     return x;
>>   }
>>   if (!(b)) return;
>> }
>> === cut here ===
>>
>> This patch fixes this by simply returning error_mark_node when 
>> detecting
>> a void return in a function returning non-void.
>>
>> Successfully tested on x86_64-pc-linux-gnu.
>>
>> 	PR c++/117099
>>
>> gcc/cp/ChangeLog:
>>
>> 	* typeck.cc (check_return_expr): Return error_mark_node upon
>> 	void return for function returning non-void.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* g++.dg/parse/crash77.C: New test.
>>
>> ---
>>  gcc/cp/typeck.cc                     |  1 +
>>  gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
>>  2 files changed, 15 insertions(+)
>>  create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C
>>
>> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
>> index 71d879abef1..22a6ec9a185 100644
>> --- a/gcc/cp/typeck.cc
>> +++ b/gcc/cp/typeck.cc
>> @@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool 
>> *no_warning, bool *dangling)
>>  	 RETURN_EXPR to avoid control reaches end of non-void function
>>  	 warnings in tree-cfg.cc.  */
>>        *no_warning = true;
>> +      return error_mark_node;
>>      }
>>    /* Check for a return statement with a value in a function that
>>       isn't supposed to return a value.  */
>> diff --git a/gcc/testsuite/g++.dg/parse/crash77.C 
>> b/gcc/testsuite/g++.dg/parse/crash77.C
>> new file mode 100644
>> index 00000000000..d3f0ae6a877
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.dg/parse/crash77.C
>> @@ -0,0 +1,14 @@
>> +// PR c++/117099
>> +// { dg-compile }
>
> dg-do compile
>
Aarg, of course, thanks for spotting this! Fixed in the attached 
version.

>> +
>> +struct X {
>> +  ~X();
>> +};
>> +
>> +X test(bool b) {
>> +  {
>> +    X x;
>> +    return x;
>> +  }
>> +  if (!(b)) return; // { dg-error "return-statement with no value" }
>> +}
>> -- 
>> 2.44.0
>>
>
> BTW, the line-endings on this seem a bit odd. Did you use 
> git-send-email?
I did use git-send-email indeed. What oddities do you see with line 
endings?
cat -A over the patch file looks good.

Thanks, Simon
From 46fcb8cd0f89213b80f2815f6b7c2af064d7e86d Mon Sep 17 00:00:00 2001
From: Simon Martin <simon@nasilyan.com>
Date: Wed, 16 Oct 2024 15:47:12 +0200
Subject: [PATCH] c++: Fix crash during NRV optimization with invalid input [PR117099]

We ICE upon the following invalid code because we end up calling
finalize_nrv_r with a RETURN_EXPR with no operand.

=== cut here ===
struct X {
  ~X();
};
X test(bool b) {
  {
    X x;
    return x;
  }
  if (!(b)) return;
}
=== cut here ===

This patch fixes this by simply returning error_mark_node when detecting
a void return in a function returning non-void.

Successfully tested on x86_64-pc-linux-gnu.

	PR c++/117099

gcc/cp/ChangeLog:

	* typeck.cc (check_return_expr): Return error_mark_node upon
	void return for function returning non-void.

gcc/testsuite/ChangeLog:

	* g++.dg/parse/crash77.C: New test.

---
 gcc/cp/typeck.cc                     |  1 +
 gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
 2 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 71d879abef1..22a6ec9a185 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling)
 	 RETURN_EXPR to avoid control reaches end of non-void function
 	 warnings in tree-cfg.cc.  */
       *no_warning = true;
+      return error_mark_node;
     }
   /* Check for a return statement with a value in a function that
      isn't supposed to return a value.  */
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index 00000000000..912b997177c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,14 @@
+// PR c++/117099
+// { dg-do compile }
+
+struct X {
+  ~X();
+};
+
+X test(bool b) {
+  {
+    X x;
+    return x;
+  } 
+  if (!(b)) return; // { dg-error "return-statement with no value" }
+}
Sam James Oct. 18, 2024, 8:55 a.m. UTC | #3
Simon Martin <simon@nasilyan.com> writes:

> Hi Sam,

Hi Simon,

>
> On 16 Oct 2024, at 22:06, Sam James wrote:
>
>> Simon Martin <simon@nasilyan.com> writes:
>>
>>> We ICE upon the following invalid code because we end up calling
>>> finalize_nrv_r with a RETURN_EXPR with no operand.
>>>
>>> === cut here ===
>>> struct X {
>>>   ~X();
>>> };
>>> X test(bool b) {
>>>   {
>>>     X x;
>>>     return x;
>>>   }
>>>   if (!(b)) return;
>>> }
>>> === cut here ===
>>>
>>> This patch fixes this by simply returning error_mark_node when 
>>> detecting
>>> a void return in a function returning non-void.
>>>
>>> Successfully tested on x86_64-pc-linux-gnu.
>>>
>>> 	PR c++/117099
>>>
>>> gcc/cp/ChangeLog:
>>>
>>> 	* typeck.cc (check_return_expr): Return error_mark_node upon
>>> 	void return for function returning non-void.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> 	* g++.dg/parse/crash77.C: New test.
>>>
>>> ---
>>>  gcc/cp/typeck.cc                     |  1 +
>>>  gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
>>>  2 files changed, 15 insertions(+)
>>>  create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C
>>>
>>> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
>>> index 71d879abef1..22a6ec9a185 100644
>>> --- a/gcc/cp/typeck.cc
>>> +++ b/gcc/cp/typeck.cc
>>> @@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool 
>>> *no_warning, bool *dangling)
>>>  	 RETURN_EXPR to avoid control reaches end of non-void function
>>>  	 warnings in tree-cfg.cc.  */
>>>        *no_warning = true;
>>> +      return error_mark_node;
>>>      }
>>>    /* Check for a return statement with a value in a function that
>>>       isn't supposed to return a value.  */
>>> diff --git a/gcc/testsuite/g++.dg/parse/crash77.C 
>>> b/gcc/testsuite/g++.dg/parse/crash77.C
>>> new file mode 100644
>>> index 00000000000..d3f0ae6a877
>>> --- /dev/null
>>> +++ b/gcc/testsuite/g++.dg/parse/crash77.C
>>> @@ -0,0 +1,14 @@
>>> +// PR c++/117099
>>> +// { dg-compile }
>>
>> dg-do compile
>>
> Aarg, of course, thanks for spotting this! Fixed in the attached 
> version.
>
>>> +
>>> +struct X {
>>> +  ~X();
>>> +};
>>> +
>>> +X test(bool b) {
>>> +  {
>>> +    X x;
>>> +    return x;
>>> +  }
>>> +  if (!(b)) return; // { dg-error "return-statement with no value" }
>>> +}
>>> -- 
>>> 2.44.0
>>>
>>
>> BTW, the line-endings on this seem a bit odd. Did you use 
>> git-send-email?
> I did use git-send-email indeed. What oddities do you see with line 
> endings?
> cat -A over the patch file looks good.
>

Weird -- if I open your original email in mu4e, I see a bunch of ^M at
the end of the lines.


> Thanks, Simon
>
> [2. text/plain; 0001-c-Fix-crash-during-NRV-optimization-with-invalid-inp.patch]...
Simon Martin Oct. 19, 2024, 9:16 a.m. UTC | #4
On 18 Oct 2024, at 10:55, Sam James wrote:

> Simon Martin <simon@nasilyan.com> writes:
>
>> Hi Sam,
>
> Hi Simon,
>
>>
>> On 16 Oct 2024, at 22:06, Sam James wrote:
>>
>>> Simon Martin <simon@nasilyan.com> writes:
>>>
>>>> We ICE upon the following invalid code because we end up calling
>>>> finalize_nrv_r with a RETURN_EXPR with no operand.
>>>>
>>>> === cut here ===
>>>> struct X {
>>>>   ~X();
>>>> };
>>>> X test(bool b) {
>>>>   {
>>>>     X x;
>>>>     return x;
>>>>   }
>>>>   if (!(b)) return;
>>>> }
>>>> === cut here ===
>>>>
>>>> This patch fixes this by simply returning error_mark_node when
>>>> detecting
>>>> a void return in a function returning non-void.
>>>>
>>>> Successfully tested on x86_64-pc-linux-gnu.
>>>>
>>>> 	PR c++/117099
>>>>
>>>> gcc/cp/ChangeLog:
>>>>
>>>> 	* typeck.cc (check_return_expr): Return error_mark_node upon
>>>> 	void return for function returning non-void.
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>>
>>>> 	* g++.dg/parse/crash77.C: New test.
>>>>
>>>> ---
>>>>  gcc/cp/typeck.cc                     |  1 +
>>>>  gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
>>>>  2 files changed, 15 insertions(+)
>>>>  create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C
>>>>
>>>> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
>>>> index 71d879abef1..22a6ec9a185 100644
>>>> --- a/gcc/cp/typeck.cc
>>>> +++ b/gcc/cp/typeck.cc
>>>> @@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool
>>>> *no_warning, bool *dangling)
>>>>  	 RETURN_EXPR to avoid control reaches end of non-void function
>>>>  	 warnings in tree-cfg.cc.  */
>>>>        *no_warning = true;
>>>> +      return error_mark_node;
>>>>      }
>>>>    /* Check for a return statement with a value in a function that
>>>>       isn't supposed to return a value.  */
>>>> diff --git a/gcc/testsuite/g++.dg/parse/crash77.C
>>>> b/gcc/testsuite/g++.dg/parse/crash77.C
>>>> new file mode 100644
>>>> index 00000000000..d3f0ae6a877
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/g++.dg/parse/crash77.C
>>>> @@ -0,0 +1,14 @@
>>>> +// PR c++/117099
>>>> +// { dg-compile }
>>>
>>> dg-do compile
>>>
>> Aarg, of course, thanks for spotting this! Fixed in the attached
>> version.
>>
>>>> +
>>>> +struct X {
>>>> +  ~X();
>>>> +};
>>>> +
>>>> +X test(bool b) {
>>>> +  {
>>>> +    X x;
>>>> +    return x;
>>>> +  }
>>>> +  if (!(b)) return; // { dg-error "return-statement with no value" }
>>>> +}
>>>> -- 
>>>> 2.44.0
>>>>
>>>
>>> BTW, the line-endings on this seem a bit odd. Did you use
>>> git-send-email?
>> I did use git-send-email indeed. What oddities do you see with line
>> endings?
>> cat -A over the patch file looks good.
>>
>
> Weird -- if I open your original email in mu4e, I see a bunch of ^M at
> the end of the lines.
Strange. FWIW I’m generating and sending the patches from a MacOS box,
and there might be some weirdness coming from that. I’ll check and try
to fix.

Simon
Iain Sandoe Oct. 19, 2024, 9:57 a.m. UTC | #5
> On 19 Oct 2024, at 10:16, Simon Martin <simon@nasilyan.com> wrote:
> 
> On 18 Oct 2024, at 10:55, Sam James wrote:
> 
>> Simon Martin <simon@nasilyan.com> writes:
>> 
>>> Hi Sam,
>> 
>> Hi Simon,
>> 
>>> 
>>> On 16 Oct 2024, at 22:06, Sam James wrote:
>>> 
>>>> Simon Martin <simon@nasilyan.com> writes:
>>>> 
>>>>> We ICE upon the following invalid code because we end up calling
>>>>> finalize_nrv_r with a RETURN_EXPR with no operand.
>>>>> 
>>>>> === cut here ===
>>>>> struct X {
>>>>>  ~X();
>>>>> };
>>>>> X test(bool b) {
>>>>>  {
>>>>>    X x;
>>>>>    return x;
>>>>>  }
>>>>>  if (!(b)) return;
>>>>> }
>>>>> === cut here ===
>>>>> 
>>>>> This patch fixes this by simply returning error_mark_node when
>>>>> detecting
>>>>> a void return in a function returning non-void.
>>>>> 
>>>>> Successfully tested on x86_64-pc-linux-gnu.
>>>>> 
>>>>> 	PR c++/117099
>>>>> 
>>>>> gcc/cp/ChangeLog:
>>>>> 
>>>>> 	* typeck.cc (check_return_expr): Return error_mark_node upon
>>>>> 	void return for function returning non-void.
>>>>> 
>>>>> gcc/testsuite/ChangeLog:
>>>>> 
>>>>> 	* g++.dg/parse/crash77.C: New test.
>>>>> 
>>>>> ---
>>>>> gcc/cp/typeck.cc                     |  1 +
>>>>> gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
>>>>> 2 files changed, 15 insertions(+)
>>>>> create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C
>>>>> 
>>>>> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
>>>>> index 71d879abef1..22a6ec9a185 100644
>>>>> --- a/gcc/cp/typeck.cc
>>>>> +++ b/gcc/cp/typeck.cc
>>>>> @@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool
>>>>> *no_warning, bool *dangling)
>>>>> 	 RETURN_EXPR to avoid control reaches end of non-void function
>>>>> 	 warnings in tree-cfg.cc.  */
>>>>>       *no_warning = true;
>>>>> +      return error_mark_node;
>>>>>     }
>>>>>   /* Check for a return statement with a value in a function that
>>>>>      isn't supposed to return a value.  */
>>>>> diff --git a/gcc/testsuite/g++.dg/parse/crash77.C
>>>>> b/gcc/testsuite/g++.dg/parse/crash77.C
>>>>> new file mode 100644
>>>>> index 00000000000..d3f0ae6a877
>>>>> --- /dev/null
>>>>> +++ b/gcc/testsuite/g++.dg/parse/crash77.C
>>>>> @@ -0,0 +1,14 @@
>>>>> +// PR c++/117099
>>>>> +// { dg-compile }
>>>> 
>>>> dg-do compile
>>>> 
>>> Aarg, of course, thanks for spotting this! Fixed in the attached
>>> version.
>>> 
>>>>> +
>>>>> +struct X {
>>>>> +  ~X();
>>>>> +};
>>>>> +
>>>>> +X test(bool b) {
>>>>> +  {
>>>>> +    X x;
>>>>> +    return x;
>>>>> +  }
>>>>> +  if (!(b)) return; // { dg-error "return-statement with no value" }
>>>>> +}
>>>>> -- 
>>>>> 2.44.0
>>>>> 
>>>> 
>>>> BTW, the line-endings on this seem a bit odd. Did you use
>>>> git-send-email?
>>> I did use git-send-email indeed. What oddities do you see with line
>>> endings?
>>> cat -A over the patch file looks good.
>>> 
>> 
>> Weird -- if I open your original email in mu4e, I see a bunch of ^M at
>> the end of the lines.
> Strange. FWIW I’m generating and sending the patches from a MacOS box,
> and there might be some weirdness coming from that. I’ll check and try
> to fix.

macOS Mail messes up whitespace, for sure (but I’ve not seen it append <CR>).
AFAIK  “git send-email” works fine (at least no-one has reported a problem).

maybe the editor in use thinks the target format is Windows and has changed
line endings accordingly?

Iain


> 
> Simon
Simon Martin Oct. 30, 2024, 4:16 p.m. UTC | #6
Hi,

Just closing the loop on this...

On 19 Oct 2024, at 11:57, Iain Sandoe wrote:

On 19 Oct 2024, at 10:16, Simon Martin <simon@nasilyan.com> wrote:

On 18 Oct 2024, at 10:55, Sam James wrote:

Simon Martin <simon@nasilyan.com> writes:

Hi Sam,

Hi Simon,

On 16 Oct 2024, at 22:06, Sam James wrote:

Simon Martin <simon@nasilyan.com> writes:

We ICE upon the following invalid code because we end up calling
finalize_nrv_r with a RETURN_EXPR with no operand.

=== cut here ===
struct X {
 ~X();
};
X test(bool b) {
 {
 X x;
 return x;
 }
 if (!(b)) return;
}
=== cut here ===

This patch fixes this by simply returning error_mark_node when
detecting
a void return in a function returning non-void.

Successfully tested on x86_64-pc-linux-gnu.

PR c++/117099

gcc/cp/ChangeLog:

* typeck.cc (check_return_expr): Return error_mark_node upon
void return for function returning non-void.

gcc/testsuite/ChangeLog:

* g++.dg/parse/crash77.C: New test.

---
gcc/cp/typeck.cc | 1 +
gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
2 files changed, 15 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 71d879abef1..22a6ec9a185 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool
*no_warning, bool *dangling)
 RETURN_EXPR to avoid control reaches end of non-void function
 warnings in tree-cfg.cc. */
 *no_warning = true;
+ return error_mark_node;
 }
 /* Check for a return statement with a value in a function that
 isn't supposed to return a value. */
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C
b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index 00000000000..d3f0ae6a877
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,14 @@
+// PR c++/117099
+// { dg-compile }

dg-do compile

Aarg, of course, thanks for spotting this! Fixed in the attached
version.

+
+struct X {
+ ~X();
+};
+
+X test(bool b) {
+ {
+ X x;
+ return x;
+ }
+ if (!(b)) return; // { dg-error "return-statement with no value" }
+}
Simon Martin Oct. 30, 2024, 4:23 p.m. UTC | #7
[ Resending since this was somehow sent in HMTL mode and was scrubbed ]

On 30 Oct 2024, at 17:16, Simon Martin wrote:

> Hi,
>
> Just closing the loop on this...
>
> On 19 Oct 2024, at 11:57, Iain Sandoe wrote:
>
> On 19 Oct 2024, at 10:16, Simon Martin <simon@nasilyan.com> wrote:
>
> On 18 Oct 2024, at 10:55, Sam James wrote:
>
> Simon Martin <simon@nasilyan.com> writes:
>
> Hi Sam,
>
> Hi Simon,
>
> On 16 Oct 2024, at 22:06, Sam James wrote:
>
> Simon Martin <simon@nasilyan.com> writes:
>
> We ICE upon the following invalid code because we end up calling
> finalize_nrv_r with a RETURN_EXPR with no operand.
>
> === cut here ===
> struct X {
>  ~X();
> };
> X test(bool b) {
>  {
>  X x;
>  return x;
>  }
>  if (!(b)) return;
> }
> === cut here ===
>
> This patch fixes this by simply returning error_mark_node when
> detecting
> a void return in a function returning non-void.
>
> Successfully tested on x86_64-pc-linux-gnu.
>
> PR c++/117099
>
> gcc/cp/ChangeLog:
>
> * typeck.cc (check_return_expr): Return error_mark_node upon
> void return for function returning non-void.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/parse/crash77.C: New test.
>
> ---
> gcc/cp/typeck.cc | 1 +
> gcc/testsuite/g++.dg/parse/crash77.C | 14 ++++++++++++++
> 2 files changed, 15 insertions(+)
> create mode 100644 gcc/testsuite/g++.dg/parse/crash77.C
>
> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
> index 71d879abef1..22a6ec9a185 100644
> --- a/gcc/cp/typeck.cc
> +++ b/gcc/cp/typeck.cc
> @@ -11238,6 +11238,7 @@ check_return_expr (tree retval, bool
> *no_warning, bool *dangling)
>  RETURN_EXPR to avoid control reaches end of non-void function
>  warnings in tree-cfg.cc. */
>  *no_warning = true;
> + return error_mark_node;
>  }
>  /* Check for a return statement with a value in a function that
>  isn't supposed to return a value. */
> diff --git a/gcc/testsuite/g++.dg/parse/crash77.C
> b/gcc/testsuite/g++.dg/parse/crash77.C
> new file mode 100644
> index 00000000000..d3f0ae6a877
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/parse/crash77.C
> @@ -0,0 +1,14 @@
> +// PR c++/117099
> +// { dg-compile }
>
> dg-do compile
>
> Aarg, of course, thanks for spotting this! Fixed in the attached
> version.
>
> +
> +struct X {
> + ~X();
> +};
> +
> +X test(bool b) {
> + {
> + X x;
> + return x;
> + }
> + if (!(b)) return; // { dg-error "return-statement with no value" }
> +}
> -- 
> 2.44.0
>
> BTW, the line-endings on this seem a bit odd. Did you use
> git-send-email?
>
> I did use git-send-email indeed. What oddities do you see with line
> endings?
> cat -A over the patch file looks good.
>
> Weird -- if I open your original email in mu4e, I see a bunch of ^M at
> the end of the lines.
>
> Strange. FWIW I’m generating and sending the patches from a MacOS 
> box,
> and there might be some weirdness coming from that. I’ll check and 
> try
> to fix.
>
> macOS Mail messes up whitespace, for sure (but I’ve not seen it 
> append <CR>).
> AFAIK “git send-email” works fine (at least no-one has reported a 
> problem).
>
> maybe the editor in use thinks the target format is Windows and has 
> changed
> line endings accordingly?
>
> I investigated further and the issue was actually linked to the AWS
> WorkMail SMTP server: when I use the native AWS SES one instead, my 
> test
>
> messages don’t have any =0D=0A anymore.
>
I’ve permanently updated my configuration to use SES, and all my 
future
git send-email’s should be good (note that this was purely a SMTP 
issue,
and the commits that I actually pushed never had any \r).

Thanks, Simon
diff mbox series

Patch

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 71d879abef1..22a6ec9a185 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11238,6 +11238,7 @@  check_return_expr (tree retval, bool *no_warning, bool *dangling)
 	 RETURN_EXPR to avoid control reaches end of non-void function
 	 warnings in tree-cfg.cc.  */
       *no_warning = true;
+      return error_mark_node;
     }
   /* Check for a return statement with a value in a function that
      isn't supposed to return a value.  */
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index 00000000000..d3f0ae6a877
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,14 @@ 
+// PR c++/117099
+// { dg-compile }
+
+struct X {
+  ~X();
+};
+
+X test(bool b) {
+  {
+    X x;
+    return x;
+  } 
+  if (!(b)) return; // { dg-error "return-statement with no value" }
+}