This is an ICE that started with the recent r275745. The problem here is that for a POSTINCREMENT_EXPR build_new_op_1 is called with null arg2, so arg2_type is also null after 5819 tree arg2_type = arg2 ? unlowered_expr_type (arg2) : NULL_TREE; but then we make arg2 nonnull 5887 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) 5888 arg2 = integer_zero_node; while arg2_type is still null and so 5940 else if (! arg2 || ! CLASS_TYPE_P (arg2_type)) crashes. Fixed by setting arg2_type in the ++/-- case.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-09-19 Marek Polacek <pola...@redhat.com> PR c++/91819 - ICE with operator++ and enum. * call.c (build_new_op_1): Set arg2_type. * g++.dg/other/operator4.C: New test. diff --git gcc/cp/call.c gcc/cp/call.c index b780b0af58e..512421b4772 100644 --- gcc/cp/call.c +++ gcc/cp/call.c @@ -5878,7 +5878,10 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, goto builtin; if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) - arg2 = integer_zero_node; + { + arg2 = integer_zero_node; + arg2_type = integer_type_node; + } vec_alloc (arglist, 3); arglist->quick_push (arg1); diff --git gcc/testsuite/g++.dg/other/operator4.C gcc/testsuite/g++.dg/other/operator4.C new file mode 100644 index 00000000000..e7a41c01a58 --- /dev/null +++ gcc/testsuite/g++.dg/other/operator4.C @@ -0,0 +1,22 @@ +// PR c++/91819 - ICE with operator++ and enum. +// { dg-do compile } + +enum Foo +{ + a, + b +}; + +inline Foo operator++(Foo &f, int) +{ + return f = (Foo)(f + 1); +} + +int main() +{ + int count = 0; + for (Foo f = a; f <= b; f++) { + count++; + } + return count; +}