]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix spurious -Wduplicated-branches for new (nothrow) T[n] [PR125422]
authorJoe Natter <johannes.natter@outlook.at>
Thu, 21 May 2026 18:20:16 +0000 (20:20 +0200)
committerJason Merrill <jason@redhat.com>
Mon, 1 Jun 2026 22:18:41 +0000 (18:18 -0400)
When allocating an array of a trivial type with new (nothrow),
build_new_1() may emit a compiler-generated COND_EXPR of the form

  (alloc_node != nullptr) ? rval : alloc_node

For trivial arrays without constructors, destructors, or array cookies,
rval remains equal to data_addr and is therefore equivalent to
alloc_node.  This causes both branches of the generated COND_EXPR to be
identical, triggering -Wduplicated-branches on user code.

Avoid building the null-check COND_EXPR when rval == data_addr.

gcc/cp/ChangeLog:
PR c++/125422
* init.cc (build_new_1): Avoid building a null-check
COND_EXPR when rval == data_addr.

gcc/testsuite/ChangeLog:
PR c++/125422
* g++.dg/warn/Wduplicated-branches10.C: New test.

Signed-off-by: Joe Natter <johannes.natter@outlook.at>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/init.cc
gcc/testsuite/g++.dg/warn/Wduplicated-branches10.C [new file with mode: 0644]

index 14ceafa682848fd45b626aa20c086d74dac8ee95..8d0018a31cc008a9c58e0e115ddd6bad91c48402 100644 (file)
@@ -3970,6 +3970,12 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
     rval = TARGET_EXPR_INITIAL (alloc_expr);
   else
     {
+      /* Skip the null-check when rval == data_addr: the resulting conditional
+        would be "alloc_node != nullptr ? alloc_node : alloc_node", triggering
+        -Wduplicated-branches (PR125422).  */
+      if (rval == data_addr)
+       check_new = 0;
+
       if (check_new)
        {
          tree ifexp = cp_build_binary_op (input_location,
diff --git a/gcc/testsuite/g++.dg/warn/Wduplicated-branches10.C b/gcc/testsuite/g++.dg/warn/Wduplicated-branches10.C
new file mode 100644 (file)
index 0000000..0ebccd7
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/125422
+// { dg-do compile }
+// { dg-options "-Wduplicated-branches" }
+
+// new (nothrow) T[n] with a runtime variable must not trigger
+// -Wduplicated-branches (false positive from compiler-generated COND_EXPR).
+
+#include <new>
+
+void
+test_nothrow (int sz)
+{
+  char *p = new (std::nothrow) char[sz];
+  delete[] p;
+}