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