https://gcc.gnu.org/g:6cd1daf5206d9e0b2da84bf587c487f68aabd8db

commit r14-11296-g6cd1daf5206d9e0b2da84bf587c487f68aabd8db
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Feb 7 14:30:11 2025 +0100

    c++: Don't use CLEANUP_EH_ONLY for new expression cleanup [PR118763]
    
    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.
    
    2025-02-07  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.
    
    (cherry picked from commit fcecc74cb38723457a0447924d9993b31252a8f9)

Diff:
---
 gcc/cp/init.cc                       |  1 -
 gcc/testsuite/g++.dg/asan/pr118763.C | 15 +++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 22d93793a4d8..e622547a092f 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -3826,7 +3826,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, 
tree nelts,
          tree end, sentry, begin;
 
          begin = get_target_expr (boolean_true_node);
-         CLEANUP_EH_ONLY (begin) = 1;
 
          sentry = TARGET_EXPR_SLOT (begin);
 
diff --git a/gcc/testsuite/g++.dg/asan/pr118763.C 
b/gcc/testsuite/g++.dg/asan/pr118763.C
new file mode 100644
index 000000000000..401528583ed3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr118763.C
@@ -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);
+}

Reply via email to