https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91415
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- On top of the above, I've tried: --- gcc/c-family/c-common.c.jj 2019-08-12 09:45:54.463491950 +0200 +++ gcc/c-family/c-common.c 2019-08-12 12:01:32.783135654 +0200 @@ -1933,16 +1934,19 @@ verify_tree (tree x, struct tlist **pbef tmp_before = tmp_nosp = tmp_list3 = 0; verify_tree (TREE_OPERAND (x, 1), &tmp_before, &tmp_nosp, NULL_TREE); verify_tree (TREE_OPERAND (x, 0), &tmp_list3, &tmp_list3, x); - /* Expressions inside the LHS are not ordered wrt. the sequence points - in the RHS. Example: + /* In C and C++ before 17 expressions inside the LHS are not ordered + wrt. the sequence points in the RHS. Example: *a = (a++, 2) Despite the fact that the modification of "a" is in the before_sp list (tmp_before), it conflicts with the use of "a" in the LHS. We can handle this by adding the contents of tmp_list3 to those of tmp_before, and redoing the collision warnings for that list. */ - add_tlist (&tmp_before, tmp_list3, x, 1); - warn_for_collisions (tmp_before); + if (cxx_dialect < cxx17) + { + add_tlist (&tmp_before, tmp_list3, x, 1); + warn_for_collisions (tmp_before); + } /* Exclude the LHS itself here; we first have to merge it into the tmp_nosp list. This is done to avoid warning for "a = a"; if we didn't exclude the LHS, we'd get it twice, once as a read and once --- gcc/testsuite/g++.dg/warn/sequence-pt-1.C.jj 2011-07-11 10:39:37.000000000 +0200 +++ gcc/testsuite/g++.dg/warn/sequence-pt-1.C 2019-08-12 12:22:42.033011124 +0200 @@ -35,7 +35,7 @@ foo (int a, int b, int n, int p, int *pt *ptr++ = (size_t)ptr++; /* { dg-warning "undefined" "sequence point warning" } */ sptr->a = sptr->a++; /* { dg-warning "undefined" "sequence point warning" } */ sptr->a = (size_t)(sptr++); /* { dg-warning "undefined" "sequence point warning" } */ - *ptr++ = fn (*ptr); /* { dg-warning "undefined" "sequence point warning" } */ + *ptr++ = fn (*ptr); /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ a = b = a++; /* { dg-warning "undefined" "sequence point warning" } */ b = a = --b; /* { dg-warning "undefined" "sequence point warning" } */ a = 1 + (a = 1); /* { dg-warning "undefined" "sequence point warning" } */ @@ -47,13 +47,13 @@ foo (int a, int b, int n, int p, int *pt a = (*fnp[b++]) (b++); /* { dg-warning "undefined" "sequence point warning" } */ a = (*fnp[b]) (b++); /* { dg-warning "undefined" "sequence point warning" } */ a = (*fnp[b++]) (b); /* { dg-warning "undefined" "sequence point warning" } */ - *ap = fnc (ap++); /* { dg-warning "undefined" "sequence point warning" } */ + *ap = fnc (ap++); /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ (a += b) + (a += n); /* { dg-warning "undefined" "sequence point warning" } */ a = (b, b++) + (b++, b); /* { dg-warning "undefined" "sequence point warning" } */ ap[a++] += a; /* { dg-warning "undefined" "sequence point warning" } */ ap[a+=1] += a; /* { dg-warning "undefined" "sequence point warning" } */ - ap[a++] += a++; /* { dg-warning "undefined" "sequence point warning" } */ - ap[a+=1] += a++; /* { dg-warning "undefined" "sequence point warning" } */ + ap[a++] += a++; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ + ap[a+=1] += a++; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ a = a++, b = a; /* { dg-warning "undefined" "sequence point warning" } */ b = a, a = a++; /* { dg-warning "undefined" "sequence point warning" } */ a = (b++ ? n : a) + b; /* { dg-warning "undefined" "sequence point warning" } */ to handle the assignment operator, but while that handles some cases as shown in the testsuite that IMHO are now well defined in C++17, it doesn't handle the case from the testcase: void foo (int i, int y[10]) { y[i++] = y[i++]; } So I probably don't understand the code well enough :(. And the PMF case is something to be resolved later too.