Hi! The following testcase is miscompiled since r12-6325 stopped preevaluating the initializers for new expression. If evaluating the initializers throws, there is a correct cleanup for that, but it is marked CLEANUP_EH_ONLY. While in standard C++ that is just fine, if it has statement expressions, it can return or goto out of the expression and we should delete the pointer in that case too.
There is already a sentry variable initialized to true and set to false after everything is initialized and used as a guard for the cleanup, so just removing the CLEANUP_EH_ONLY flag does everything we need. And in the normal case of the initializer not using statement expressions at least with -O2 we get the same code, while the change changes one try { sentry = true; ... sentry = false; } catch { if (sentry) delete ...; } into try { sentry = true; ... sentry = false; } finally { if (sentry) delete ...; } optimizations will see that sentry is false when reaching the finally other than through an exception. Though, wonder what other CLEANUP_EH_ONLY cleanups might be an issue with statement expressions. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-02-06 Jakub Jelinek <ja...@redhat.com> PR c++/118763 * init.cc (build_new_1): Don't set CLEANUP_EH_ONLY. * g++.dg/asan/pr118763.C: New test. --- gcc/cp/init.cc.jj 2025-02-04 21:54:35.102087948 +0100 +++ gcc/cp/init.cc 2025-02-06 12:25:17.624810169 +0100 @@ -3842,7 +3842,6 @@ build_new_1 (vec<tree, va_gc> **placemen tree end, sentry, begin; begin = get_target_expr (boolean_true_node); - CLEANUP_EH_ONLY (begin) = 1; sentry = TARGET_EXPR_SLOT (begin); --- gcc/testsuite/g++.dg/asan/pr118763.C.jj 2025-02-06 12:23:50.724022482 +0100 +++ gcc/testsuite/g++.dg/asan/pr118763.C 2025-02-06 12:23:29.407319860 +0100 @@ -0,0 +1,15 @@ +// PR c++/118763 +// { dg-do run } + +int * +foo (bool x) +{ + return new int (({ if (x) return nullptr; 1; })); +} + +int +main () +{ + delete foo (true); + delete foo (false); +} Jakub