]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Don't use CLEANUP_EH_ONLY for new expression cleanup [PR118763]
authorJakub Jelinek <jakub@redhat.com>
Fri, 7 Feb 2025 13:30:11 +0000 (14:30 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 7 Feb 2025 13:30:11 +0000 (14:30 +0100)
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  <jakub@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
gcc/testsuite/g++.dg/asan/pr118763.C [new file with mode: 0644]

index 613775c5a7c821c9ddd08c507a248264d803e1fa..20f4408cc9a19158652dedaec90d9fa5fd164c30 100644 (file)
@@ -3842,7 +3842,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 (file)
index 0000000..4015285
--- /dev/null
@@ -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);
+}