aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSimon Martin <simon@nasilyan.com>2024-11-05 10:44:34 +0100
committerSimon Martin <simon@nasilyan.com>2024-11-05 10:44:34 +0100
commitf31b72b75ef7cde61469c774162db7b1cc4c3d03 (patch)
treed765bfddc1bab768dfe0a144c0faa2d4206090f9 /gcc
parent5821f5c8c89a054e34cea00e042996dfdcd7e102 (diff)
downloadgcc-f31b72b75ef7cde61469c774162db7b1cc4c3d03.zip
gcc-f31b72b75ef7cde61469c774162db7b1cc4c3d03.tar.gz
gcc-f31b72b75ef7cde61469c774162db7b1cc4c3d03.tar.bz2
c++: Fix crash during NRV optimization with invalid input [PR117099, PR117129]
PR117099 and PR117129 are ICEs upon invalid code that happen when NRVO is activated, and both due to the fact that we don't consistently set current_function_return_value to error_mark_node upon error in finish_return_expr. This patch fixes this inconsistency which fixes both cases since we skip calling finalize_nrv when current_function_return_value is error_mark_node. PR c++/117099 PR c++/117129 gcc/cp/ChangeLog: * typeck.cc (check_return_expr): Upon error, set current_function_return_value to error_mark_node. gcc/testsuite/ChangeLog: * g++.dg/parse/crash78.C: New test. * g++.dg/parse/crash78a.C: New test. * g++.dg/parse/crash79.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/typeck.cc8
-rw-r--r--gcc/testsuite/g++.dg/parse/crash78.C15
-rw-r--r--gcc/testsuite/g++.dg/parse/crash78a.C22
-rw-r--r--gcc/testsuite/g++.dg/parse/crash79.C15
4 files changed, 59 insertions, 1 deletions
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 4396812..4c15e26 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11239,6 +11239,8 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling)
"function returning %qT", valtype);
/* Remember that this function did return. */
current_function_returns_value = 1;
+ /* But suppress NRV .*/
+ current_function_return_value = error_mark_node;
/* And signal caller that TREE_NO_WARNING should be set on the
RETURN_EXPR to avoid control reaches end of non-void function
warnings in tree-cfg.cc. */
@@ -11449,7 +11451,11 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling)
/* If the conversion failed, treat this just like `return;'. */
if (retval == error_mark_node)
- return retval;
+ {
+ /* And suppress NRV. */
+ current_function_return_value = error_mark_node;
+ return retval;
+ }
/* We can't initialize a register from a AGGR_INIT_EXPR. */
else if (! cfun->returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
diff --git a/gcc/testsuite/g++.dg/parse/crash78.C b/gcc/testsuite/g++.dg/parse/crash78.C
new file mode 100644
index 0000000..f30fe08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash78.C
@@ -0,0 +1,15 @@
+// PR c++/117099
+// { dg-do "compile" }
+
+struct X {
+ ~X();
+};
+
+X test(bool b) {
+ {
+ X x;
+ return x;
+ }
+ return X();
+ if (!(b)) return; // { dg-error "return-statement with no value" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash78a.C b/gcc/testsuite/g++.dg/parse/crash78a.C
new file mode 100644
index 0000000..241a5e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash78a.C
@@ -0,0 +1,22 @@
+// PR c++/117099
+// With -fpermissive, make sure we don't do NRV in this case, but keep
+// executing fine. Note that the return at line 16 is undefined behaviour.
+// { dg-do "run" }
+// { dg-options "-fpermissive" }
+
+struct X {
+ ~X() {}
+};
+
+X test(bool b) {
+ X x;
+ if (b)
+ return x;
+ else
+ return; // { dg-warning "return-statement with no value" }
+}
+
+int main(int, char*[]) {
+ (void) test (false);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash79.C b/gcc/testsuite/g++.dg/parse/crash79.C
new file mode 100644
index 0000000..08d62af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash79.C
@@ -0,0 +1,15 @@
+// PR c++/117129
+// { dg-do "compile" { target c++11 } }
+
+struct Noncopyable {
+ Noncopyable();
+ Noncopyable(const Noncopyable &) = delete; // { dg-note "declared here" }
+ virtual ~Noncopyable();
+};
+Noncopyable nrvo() {
+ {
+ Noncopyable A;
+ return A; // { dg-error "use of deleted function" }
+ // { dg-note "display considered" "" { target *-*-* } .-1 }
+ }
+}