https://gcc.gnu.org/g:d26c166001d6a5bdfd94be6e6d17135669ed340b
commit r15-6089-gd26c166001d6a5bdfd94be6e6d17135669ed340b Author: Marek Polacek <pola...@redhat.com> Date: Mon Dec 9 15:36:25 2024 -0500 c++: ICE with -Wduplicated-branches in template [PR117880] In a template, for things like void() we'll create a CAST_EXPR with a null operand. That causes a crash with -Wduplicated-branches on: false ? void() : void(); because we do if (warn_duplicated_branches && (complain & tf_warning) && (arg2 == arg3 || operand_equal_p (arg2, arg3, OEP_ADDRESS_OF_SAME_FIELD))) even in a template. So one way to fix the ICE would be to check !processing_template_decl. But we can also do the following and continue warning even in templates. This ICE appeared with the removal of NON_DEPENDENT_EXPR; before, operand_equal_p would bail on this code so there was no problem. PR c++/117880 gcc/ChangeLog: * fold-const.cc (operand_compare::operand_equal_p) <case tcc_unary>: Use OP_SAME_WITH_NULL instead of OP_SAME. gcc/testsuite/ChangeLog: * g++.dg/warn/Wduplicated-branches8.C: New test. Reviewed-by: Jason Merrill <ja...@redhat.com> Diff: --- gcc/fold-const.cc | 2 +- gcc/testsuite/g++.dg/warn/Wduplicated-branches8.C | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 2e18553eb549..af2851ec0919 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -3470,7 +3470,7 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, break; } - return OP_SAME (0); + return OP_SAME_WITH_NULL (0); case tcc_comparison: diff --git a/gcc/testsuite/g++.dg/warn/Wduplicated-branches8.C b/gcc/testsuite/g++.dg/warn/Wduplicated-branches8.C new file mode 100644 index 000000000000..f03c92a2c8b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wduplicated-branches8.C @@ -0,0 +1,17 @@ +// PR c++/117880 +// { dg-do compile } +// { dg-options "-Wduplicated-branches" } + +struct X {}; + +template<typename> +struct S { + void g1 () { false ? void() : void(); } // { dg-warning "this condition has identical branches" } + void g2 () { false ? int() : int(); } // { dg-warning "this condition has identical branches" } + void g3 () { int() ? : int(); } // { dg-warning "this condition has identical branches" } + void g4 () { false ? int() : double(); } + void g5 () { false ? unsigned() : int(); } + void g6 () { false ? signed() : int(); } // { dg-warning "this condition has identical branches" } + // Two different TARGET_EXPRs. + void g7 () { false ? X() : X(); } +};