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 <jason@redhat.com>
break;
}
- return OP_SAME (0);
+ return OP_SAME_WITH_NULL (0);
case tcc_comparison:
--- /dev/null
+// 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(); }
+};