Hi! As the testcase shows, with -fpermissive we call operator++() or operator--() if operator++(int) or operator--(int) is not available, but the new code in build_min_non_dep_op_overload wasn't expecting such a change. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-02-06 Jakub Jelinek <ja...@redhat.com> PR c++/79377 * tree.c (build_min_non_dep_op_overload): For POST{INC,DEC}REMENT_EXPR allow one fewer than expected arguments if flag_permissive. * g++.dg/lookup/pr79377.C: New test. --- gcc/cp/tree.c.jj 2017-01-26 20:35:13.000000000 +0100 +++ gcc/cp/tree.c 2017-02-06 17:30:26.101413319 +0100 @@ -2938,8 +2938,10 @@ build_min_non_dep_op_overload (enum tree nargs = call_expr_nargs (non_dep); expected_nargs = cp_tree_code_length (op); - if (op == POSTINCREMENT_EXPR - || op == POSTDECREMENT_EXPR) + if ((op == POSTINCREMENT_EXPR + || op == POSTDECREMENT_EXPR) + /* With -fpermissive non_dep could be operator++(). */ + && (!flag_permissive || nargs != expected_nargs)) expected_nargs += 1; gcc_assert (nargs == expected_nargs); --- gcc/testsuite/g++.dg/lookup/pr79377.C.jj 2017-02-06 17:41:22.316931623 +0100 +++ gcc/testsuite/g++.dg/lookup/pr79377.C 2017-02-06 17:37:09.000000000 +0100 @@ -0,0 +1,36 @@ +// PR c++/79377 +// { dg-do run } +// { dg-options "-fpermissive" } + +struct A +{ + A () : a (0) {} + A& operator++ () { ++a; ++c; return *this; } + int a; + static int c; +}; + +int A::c = 0; + +template <typename> +void +foo (A& a) +{ + a++; // { dg-warning "trying prefix operator instead" } + if (A::c != 3 || a.a != 3) __builtin_abort (); + ++a; + if (A::c != 4 || a.a != 4) __builtin_abort (); +} + +int +main () +{ + A a; + if (A::c != 0 || a.a != 0) __builtin_abort (); + ++a; + if (A::c != 1 || a.a != 1) __builtin_abort (); + a++; // { dg-warning "trying prefix operator instead" } + if (A::c != 2 || a.a != 2) __builtin_abort (); + foo<int> (a); + if (A::c != 4 || a.a != 4) __builtin_abort (); +} Jakub