From: Marek Polacek Date: Mon, 9 Dec 2024 20:36:25 +0000 (-0500) Subject: c++: ICE with -Wduplicated-branches in template [PR117880] X-Git-Tag: basepoints/gcc-16~3464 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d26c166001d6a5bdfd94be6e6d17135669ed340b;p=thirdparty%2Fgcc.git 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) : Use OP_SAME_WITH_NULL instead of OP_SAME. gcc/testsuite/ChangeLog: * g++.dg/warn/Wduplicated-branches8.C: New test. Reviewed-by: Jason Merrill --- 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 +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(); } +};