https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120940

            Bug ID: 120940
           Summary: [15 Regression] False positive -Wduplicated-branches
                    warning
           Product: gcc
           Version: 15.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sirl at gcc dot gnu.org
  Target Milestone: ---

This small code snippet warns with r15-9900 (r15-9866 was still OK):

static const char Names[16][8]    = { "ac0", "ac1", "ac2", "ac3", "t0", "t1",
"t2", "t3", "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7" };
static const char NamesPh2[16][8] = { "ac0", "ac1", "ac2", "ac3", "dr0", "dr1",
"dr2", "dr3", "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7" };

const char * test(int mode, int idx)
{
        return (mode ? Names : NamesPh2)[idx];
}

# g++-15 -c -Wduplicated-branches test-Wduplicated-branches.cpp -O2
test-Wduplicated-branches.cpp: In function 'const char* test(int, int)':
test-Wduplicated-branches.cpp:7:45: warning: this condition has identical
branches [-Wduplicated-branches]
    7 |         return (mode ? Names : NamesPh2)[idx];
      |                                             ^
test-Wduplicated-branches.cpp:7:45: warning: this condition has identical
branches [-Wduplicated-branches]
    7 |         return (mode ? Names : NamesPh2)[idx];
      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^


Looking at the changelog it seems like this change maybe the culprit:

commit r15-9896-g7fdf47538a659f6af8dadbecbb63c8a226b63754
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Jul 1 15:28:10 2025 +0200

    c++: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

    The following testcase is miscompiled since the introduction of UBSan,
    cp_build_array_ref COND_EXPR handling replaces
    (cond ? a : b)[idx] with cond ? a[idx] : b[idx], but if there are
    SAVE_EXPRs inside of idx, they will be evaluated just in one of the
    branches and the other uses uninitialized temporaries.

    Fixed by keeping doing what it did if idx doesn't have side effects
    and is invariant.  Otherwise if op1/op2 are ARRAY_TYPE arrays with
    invariant addresses or pointers with invariant values, use
    SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as a new condition
    and SAVE_EXPR <idx> instead of idx for the recursive calls.
    Otherwise punt, but if op1/op2 are ARRAY_TYPE, furthermore call
    cp_default_conversion on array, so that COND_EXPR with ARRAY_TYPE doesn't
    survive in the IL until expansion.

    2025-07-01  Jakub Jelinek  <ja...@redhat.com>

            PR c++/120471
    gcc/cp/
            * typeck.cc (cp_build_array_ref) <case COND_EXPR>: If idx is not
            INTEGER_CST, don't optimize the case (but cp_default_conversion on
            array early if it has ARRAY_TYPE) or use
            SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as new op0
depending
            on flag_strong_eval_order and whether op1 and op2 are arrays with
            invariant address or tree invariant pointers.  Formatting fixes.
    gcc/testsuite/
            * g++.dg/ubsan/pr120471.C: New test.
            * g++.dg/parse/pr120471.C: New test.

Since this was backported to the other release branches as well, they might be
also affected.

Reply via email to