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 |
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?
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" } +}
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]...
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" } +}