diff options
author | Simon Martin <simon@nasilyan.com> | 2024-11-05 10:44:34 +0100 |
---|---|---|
committer | Simon Martin <simon@nasilyan.com> | 2024-11-05 10:44:34 +0100 |
commit | f31b72b75ef7cde61469c774162db7b1cc4c3d03 (patch) | |
tree | d765bfddc1bab768dfe0a144c0faa2d4206090f9 /gcc/cp | |
parent | 5821f5c8c89a054e34cea00e042996dfdcd7e102 (diff) | |
download | gcc-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/cp')
-rw-r--r-- | gcc/cp/typeck.cc | 8 |
1 files changed, 7 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 |