https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117980
--- Comment #11 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>: https://gcc.gnu.org/g:fa99002538bc91c869f3b1fd9af7f14e410e1e1a commit r15-6369-gfa99002538bc91c869f3b1fd9af7f14e410e1e1a Author: Marek Polacek <pola...@redhat.com> Date: Tue Dec 10 18:43:56 2024 -0500 c++: ICE in TARGET_EXPR evaluation in cp_fold_r [PR117980] This ICE started with the recent prvalue optimization (r15-6052). In cp_fold_r we have: if (tree &init = TARGET_EXPR_INITIAL (stmt)) { cp_walk_tree (&init, cp_fold_r, data, NULL); // ... tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt)); What can happen here is that originally the TARGET_EXPR is: TARGET_EXPR <D.2747, <<< Unknown tree: aggr_init_expr 5 __ct_comp D.2747 (struct subrange *) <<< Unknown tree: void_cst >>> &TARGET_EXPR <D.2707, {.it=TARGET_EXPR <D.2695, ...>}> >>>> but after the first cp_walk_tree we fold the D.2707 TARGET_EXPR into: TARGET_EXPR <D.2707, <<< Unknown tree: expr_stmt D.2707.it = TARGET_EXPR <D.2695, ...> >>>> and then we pass the EXPR_STMT to maybe_constant_init, with D.2707 as the object. But their types don't match anymore, so we crash. We'd have to pass D.2707.it as the object for it to work. This patch adjusts cxx_eval_outermost_constant_expr to take the object's type if available. constexpr-prvalue3.C is reduced from a large std::ranges libstdc++ test. PR c++/117980 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): If there's an object to initialize, take its type. Don't set the type in the constexpr dtor case. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-prvalue2.C: New test. * g++.dg/cpp0x/constexpr-prvalue3.C: New test. Co-authored-by: Jason Merrill <ja...@redhat.com>