Simon Martin <[email protected]> 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?