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


Reply via email to