Message ID | 20200516223305.251582-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Don't add built-in operator for ++ on bool. | expand |
On 5/16/20 6:33 PM, Marek Polacek wrote: > This feels extremely obscure but at least it's an opportunity to fix the > comments. P0002R1 removed deprecated operator++(bool) in C++17 so let's > avoid adding a builtin overload candidate for ++ when the type is bool. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? OK. > * call.c (add_builtin_candidate): Don't create a builtin overload > candidate for ++ when type is bool in C++17. > > * g++.dg/overload/builtin5.C: New test. > --- > gcc/cp/call.c | 18 +++++++++++------- > gcc/testsuite/g++.dg/overload/builtin5.C | 21 +++++++++++++++++++++ > 2 files changed, 32 insertions(+), 7 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/overload/builtin5.C > > diff --git a/gcc/cp/call.c b/gcc/cp/call.c > index c5871974eb1..b96bc06a364 100644 > --- a/gcc/cp/call.c > +++ b/gcc/cp/call.c > @@ -2672,19 +2672,19 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, > switch (code) > { > > -/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type, > +/* 4 For every pair (T, VQ), where T is an arithmetic type other than bool, > and VQ is either volatile or empty, there exist candidate operator > functions of the form > VQ T& operator++(VQ T&); > T operator++(VQ T&, int); > - 5 For every pair T, VQ), where T is an enumeration type or an arithmetic > - type other than bool, and VQ is either volatile or empty, there exist > - candidate operator functions of the form > + 5 For every pair (T, VQ), where T is an arithmetic type other than bool, > + and VQ is either volatile or empty, there exist candidate operator > + functions of the form > VQ T& operator--(VQ T&); > T operator--(VQ T&, int); > - 6 For every pair T, VQ), where T is a cv-qualified or cv-unqualified > - complete object type, and VQ is either volatile or empty, there exist > - candidate operator functions of the form > + 6 For every pair (T, VQ), where T is a cv-qualified or cv-unqualified object > + type, and VQ is either volatile or empty, there exist candidate operator > + functions of the form > T*VQ& operator++(T*VQ&); > T*VQ& operator--(T*VQ&); > T* operator++(T*VQ&, int); > @@ -2697,6 +2697,10 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, > /* FALLTHRU */ > case POSTINCREMENT_EXPR: > case PREINCREMENT_EXPR: > + /* P0002R1, Remove deprecated operator++(bool) added "other than bool" > + to p4. */ > + if (TREE_CODE (type1) == BOOLEAN_TYPE && cxx_dialect >= cxx17) > + return; > if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1)) > { > type1 = build_reference_type (type1); > diff --git a/gcc/testsuite/g++.dg/overload/builtin5.C b/gcc/testsuite/g++.dg/overload/builtin5.C > new file mode 100644 > index 00000000000..a30251dc79d > --- /dev/null > +++ b/gcc/testsuite/g++.dg/overload/builtin5.C > @@ -0,0 +1,21 @@ > +// { dg-do compile { target c++17 } } > +// Don't add built-in operator for ++ on bool. > + > +template<typename T> > +struct S { operator T&(); }; > + > +template<int> void > +foo (S<bool>& s) > +{ > + --s; // { dg-error "no match for" } > + ++s; // { dg-error "no match for" } > + s++; // { dg-error "declared for postfix" } > + s--; // { dg-error "declared for postfix" } > +} > + > +void > +bar () > +{ > + S<bool> s; > + foo<0> (s); > +} > > base-commit: f5b461d453043c6b6dda50db0439e4c78b241f03 >
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c5871974eb1..b96bc06a364 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2672,19 +2672,19 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, switch (code) { -/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type, +/* 4 For every pair (T, VQ), where T is an arithmetic type other than bool, and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator++(VQ T&); T operator++(VQ T&, int); - 5 For every pair T, VQ), where T is an enumeration type or an arithmetic - type other than bool, and VQ is either volatile or empty, there exist - candidate operator functions of the form + 5 For every pair (T, VQ), where T is an arithmetic type other than bool, + and VQ is either volatile or empty, there exist candidate operator + functions of the form VQ T& operator--(VQ T&); T operator--(VQ T&, int); - 6 For every pair T, VQ), where T is a cv-qualified or cv-unqualified - complete object type, and VQ is either volatile or empty, there exist - candidate operator functions of the form + 6 For every pair (T, VQ), where T is a cv-qualified or cv-unqualified object + type, and VQ is either volatile or empty, there exist candidate operator + functions of the form T*VQ& operator++(T*VQ&); T*VQ& operator--(T*VQ&); T* operator++(T*VQ&, int); @@ -2697,6 +2697,10 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, /* FALLTHRU */ case POSTINCREMENT_EXPR: case PREINCREMENT_EXPR: + /* P0002R1, Remove deprecated operator++(bool) added "other than bool" + to p4. */ + if (TREE_CODE (type1) == BOOLEAN_TYPE && cxx_dialect >= cxx17) + return; if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1)) { type1 = build_reference_type (type1); diff --git a/gcc/testsuite/g++.dg/overload/builtin5.C b/gcc/testsuite/g++.dg/overload/builtin5.C new file mode 100644 index 00000000000..a30251dc79d --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/builtin5.C @@ -0,0 +1,21 @@ +// { dg-do compile { target c++17 } } +// Don't add built-in operator for ++ on bool. + +template<typename T> +struct S { operator T&(); }; + +template<int> void +foo (S<bool>& s) +{ + --s; // { dg-error "no match for" } + ++s; // { dg-error "no match for" } + s++; // { dg-error "declared for postfix" } + s--; // { dg-error "declared for postfix" } +} + +void +bar () +{ + S<bool> s; + foo<0> (s); +}