For historical reasons, incrementing a boolean was allowed (because anything non-0 is true), while decrementing is forbidden. This has now changed, and since C++17 even ++ on bool is invalid. And C++ 03/11/14 [depr.incr.bool] says that ++ is deprecated, but we never diagnosed this.
A bunch of testcases needed updating, but nothing unexpected. (Even though I recently changed out documentation to use "boolean" rather than "Boolean", I'm keeping this as it is. I can tweak that in a follow up.) Bootstrapped/regtested on x86_64-linux/ppc64-linux, ok for trunk? 2016-09-13 Marek Polacek <pola...@redhat.com> * typeck.c (cp_build_unary_op): Diagnose incrementing boolean expressions. * c-c++-common/gomp/atomic-12.c: Use -Wno-deprecated. * c-c++-common/gomp/atomic-13.c: Likewise. * c-c++-common/gomp/atomic-14.c: Likewise. * g++.dg/cpp1y/lambda-init11.C: Remove invalid code. * g++.dg/cpp1z/bool-increment1.C: New test. * c-c++-common/pr60439.c: Add dg-warning. * g++.dg/expr/bitfield4.C: Likewise. * g++.dg/expr/bitfield5.C: Likewise. * g++.dg/expr/bitfield6.C: Likewise. * g++.dg/expr/bool1.C: Likewise. * g++.dg/expr/bool3.C: Likewise. * g++.dg/expr/lval3.C: Likewise. * g++.dg/expr/lval4.C: Likewise. * g++.old-deja/g++.jason/bool5.C: Likewise. diff --git gcc/cp/typeck.c gcc/cp/typeck.c index a591d29..341f722 100644 --- gcc/cp/typeck.c +++ gcc/cp/typeck.c @@ -6030,7 +6030,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, complain)) return error_mark_node; - /* Forbid using -- on `bool'. */ + /* Forbid using -- or ++ in C++17 on `bool'. */ if (TREE_CODE (declared_type) == BOOLEAN_TYPE) { if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR) @@ -6040,6 +6040,20 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, "to %<operator--%>"); return error_mark_node; } + else + { + if (cxx_dialect >= cxx1z) + { + if (complain & tf_error) + error ("use of Boolean expression as operand " + "to %<operator++%> is forbidden in C++1z"); + return error_mark_node; + } + /* Otherwise, [depr.incr.bool] says this is deprecated. */ + else if (!in_system_header_at (input_location)) + warning (OPT_Wdeprecated, "use of Boolean expression as " + "operand to %<operator++%> is deprecated"); + } val = boolean_increment (code, arg); } else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) diff --git gcc/testsuite/c-c++-common/gomp/atomic-12.c gcc/testsuite/c-c++-common/gomp/atomic-12.c index 145e420..e9ca650 100644 --- gcc/testsuite/c-c++-common/gomp/atomic-12.c +++ gcc/testsuite/c-c++-common/gomp/atomic-12.c @@ -1,6 +1,6 @@ /* PR middle-end/45423 */ /* { dg-do compile } */ -/* { dg-options "-fopenmp -fdump-tree-gimple -g0" } */ +/* { dg-options "-fopenmp -fdump-tree-gimple -g0 -Wno-deprecated" } */ /* atomicvar should never be referenced in between the barrier and following #pragma omp atomic_load. */ /* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */ diff --git gcc/testsuite/c-c++-common/gomp/atomic-13.c gcc/testsuite/c-c++-common/gomp/atomic-13.c index 2452035..7f4afcf 100644 --- gcc/testsuite/c-c++-common/gomp/atomic-13.c +++ gcc/testsuite/c-c++-common/gomp/atomic-13.c @@ -1,6 +1,6 @@ /* PR middle-end/45423 */ /* { dg-do compile } */ -/* { dg-options "-fopenmp -fdump-tree-gimple -g0 -O2" } */ +/* { dg-options "-fopenmp -fdump-tree-gimple -g0 -O2 -Wno-deprecated" } */ /* atomicvar should never be referenced in between the barrier and following #pragma omp atomic_load. */ /* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */ diff --git gcc/testsuite/c-c++-common/gomp/atomic-14.c gcc/testsuite/c-c++-common/gomp/atomic-14.c index f8fc9d8..7e23453 100644 --- gcc/testsuite/c-c++-common/gomp/atomic-14.c +++ gcc/testsuite/c-c++-common/gomp/atomic-14.c @@ -1,6 +1,6 @@ /* PR middle-end/45423 */ /* { dg-do compile } */ -/* { dg-options "-fopenmp" } */ +/* { dg-options "-fopenmp -Wno-deprecated" } */ #ifdef __cplusplus bool *baz (); diff --git gcc/testsuite/c-c++-common/pr60439.c gcc/testsuite/c-c++-common/pr60439.c index 68bd33c..71b397a 100644 --- gcc/testsuite/c-c++-common/pr60439.c +++ gcc/testsuite/c-c++-common/pr60439.c @@ -132,6 +132,7 @@ f6 (bool b) break; } switch (b++) /* { dg-warning "switch condition has" } */ + /* { dg-warning "is deprecated" "" { target c++ } 134 } */ { case 3: break; diff --git gcc/testsuite/g++.dg/cpp1y/lambda-init11.C gcc/testsuite/g++.dg/cpp1y/lambda-init11.C index f7525d8..4d434cd 100644 --- gcc/testsuite/g++.dg/cpp1y/lambda-init11.C +++ gcc/testsuite/g++.dg/cpp1y/lambda-init11.C @@ -16,5 +16,4 @@ int main(){ foo(3.14f); foo(0); foo('a'); - foo(false); } diff --git gcc/testsuite/g++.dg/expr/bitfield4.C gcc/testsuite/g++.dg/expr/bitfield4.C index d824964..7fae086 100644 --- gcc/testsuite/g++.dg/expr/bitfield4.C +++ gcc/testsuite/g++.dg/expr/bitfield4.C @@ -14,6 +14,6 @@ template <> void f(bool) {} int main() { - f(s.x++); - f(++s.x); + f(s.x++); // { dg-warning "deprecated" } + f(++s.x); // { dg-warning "deprecated" } } diff --git gcc/testsuite/g++.dg/expr/bitfield5.C gcc/testsuite/g++.dg/expr/bitfield5.C index 3d18e15..0a37f9f 100644 --- gcc/testsuite/g++.dg/expr/bitfield5.C +++ gcc/testsuite/g++.dg/expr/bitfield5.C @@ -8,10 +8,10 @@ struct S { S s; int main() { - s.x++; + s.x++; // { dg-warning "deprecated" } if (s.x != 1) return 1; - ++s.x; + ++s.x; // { dg-warning "deprecated" } if (s.x != 1) return 2; } diff --git gcc/testsuite/g++.dg/expr/bitfield6.C gcc/testsuite/g++.dg/expr/bitfield6.C index 6f6d559..8523866 100644 --- gcc/testsuite/g++.dg/expr/bitfield6.C +++ gcc/testsuite/g++.dg/expr/bitfield6.C @@ -7,5 +7,5 @@ struct S { S s; void f() { - ++s.x = false; + ++s.x = false; // { dg-warning "deprecated" } } diff --git gcc/testsuite/g++.dg/expr/bool1.C gcc/testsuite/g++.dg/expr/bool1.C index bfb40e3..503e8b4 100644 --- gcc/testsuite/g++.dg/expr/bool1.C +++ gcc/testsuite/g++.dg/expr/bool1.C @@ -10,8 +10,8 @@ int main() my_bool b = false; int i; - b++; - b++; + b++; // { dg-warning "deprecated" } + b++; // { dg-warning "deprecated" } i = b; if (i != 1) abort (); diff --git gcc/testsuite/g++.dg/expr/bool3.C gcc/testsuite/g++.dg/expr/bool3.C index 61669e2..1866ed4 100644 --- gcc/testsuite/g++.dg/expr/bool3.C +++ gcc/testsuite/g++.dg/expr/bool3.C @@ -10,8 +10,8 @@ int main() my_bool b = false; int i; - b++; - b++; + b++; // { dg-warning "deprecated" } + b++; // { dg-warning "deprecated" } i = b; if (i != 1) abort (); diff --git gcc/testsuite/g++.dg/expr/lval3.C gcc/testsuite/g++.dg/expr/lval3.C index f106e69..8e0aead 100644 --- gcc/testsuite/g++.dg/expr/lval3.C +++ gcc/testsuite/g++.dg/expr/lval3.C @@ -4,6 +4,7 @@ f() { bool i = 0; i++ = 3; // { dg-error "" } + // { dg-warning "deprecated" "" { target *-*-* } 6 } } diff --git gcc/testsuite/g++.dg/expr/lval4.C gcc/testsuite/g++.dg/expr/lval4.C index c66e2f6..b903ec8 100644 --- gcc/testsuite/g++.dg/expr/lval4.C +++ gcc/testsuite/g++.dg/expr/lval4.C @@ -4,6 +4,7 @@ f() { bool i = 0; ++i = 3; + // { dg-warning "deprecated" "" { target *-*-* } 6 } } diff --git gcc/testsuite/g++.old-deja/g++.jason/bool5.C gcc/testsuite/g++.old-deja/g++.jason/bool5.C index 1d2f5b6..0a16ccb 100644 --- gcc/testsuite/g++.old-deja/g++.jason/bool5.C +++ gcc/testsuite/g++.old-deja/g++.jason/bool5.C @@ -2,10 +2,10 @@ int main () { bool b = false; - int i = b++; + int i = b++; // { dg-warning "deprecated" } if (i != false || b != true) return 1; - i = b++; + i = b++; // { dg-warning "deprecated" } if (i != true || b != true) return 1; } Marek