| // RUN: %clang_cc1 -std=c++20 -verify %s |
| |
| template <class T> |
| requires(sizeof(T) > 2) || T::value // #FOO_REQ |
| void Foo(T){}; // #FOO |
| |
| template <class T> |
| void TrailingReturn(T) // #TRAILING |
| requires(sizeof(T) > 2) || // #TRAILING_REQ |
| T::value // #TRAILING_REQ_VAL |
| {}; |
| template <bool B> |
| struct HasValue { |
| static constexpr bool value = B; |
| }; |
| static_assert(sizeof(HasValue<true>) <= 2); |
| |
| template <bool B> |
| struct HasValueLarge { |
| static constexpr bool value = B; |
| int I; |
| }; |
| static_assert(sizeof(HasValueLarge<true>) > 2); |
| |
| void usage() { |
| // Passes the 1st check, short-circuit so the 2nd ::value is not evaluated. |
| Foo(1.0); |
| TrailingReturn(1.0); |
| |
| // Fails the 1st check, but has a ::value, so the check happens correctly. |
| Foo(HasValue<true>{}); |
| TrailingReturn(HasValue<true>{}); |
| |
| // Passes the 1st check, but would have passed the 2nd one. |
| Foo(HasValueLarge<true>{}); |
| TrailingReturn(HasValueLarge<true>{}); |
| |
| // Fails the 1st check, fails 2nd because there is no ::value. |
| Foo(true); |
| // expected-error@-1{{no matching function for call to 'Foo'}} |
| // expected-note@#FOO{{candidate template ignored: constraints not satisfied [with T = bool]}} |
| // expected-note@#FOO_REQ{{because 'sizeof(_Bool) > 2' (1 > 2) evaluated to false}} |
| // expected-note@#FOO_REQ{{because substituted constraint expression is ill-formed: type 'bool' cannot be used prior to '::' because it has no members}} |
| |
| TrailingReturn(true); |
| // expected-error@-1{{no matching function for call to 'TrailingReturn'}} |
| // expected-note@#TRAILING{{candidate template ignored: constraints not satisfied [with T = bool]}} |
| // expected-note@#TRAILING_REQ{{because 'sizeof(_Bool) > 2' (1 > 2) evaluated to false}} |
| // expected-note@#TRAILING_REQ_VAL{{because substituted constraint expression is ill-formed: type 'bool' cannot be used prior to '::' because it has no members}} |
| |
| // Fails the 1st check, fails 2nd because ::value is false. |
| Foo(HasValue<false>{}); |
| // expected-error@-1 {{no matching function for call to 'Foo'}} |
| // expected-note@#FOO{{candidate template ignored: constraints not satisfied [with T = HasValue<false>]}} |
| // expected-note@#FOO_REQ{{because 'sizeof(HasValue<false>) > 2' (1 > 2) evaluated to false}} |
| // expected-note@#FOO_REQ{{and 'HasValue<false>::value' evaluated to false}} |
| TrailingReturn(HasValue<false>{}); |
| // expected-error@-1 {{no matching function for call to 'TrailingReturn'}} |
| // expected-note@#TRAILING{{candidate template ignored: constraints not satisfied [with T = HasValue<false>]}} |
| // expected-note@#TRAILING_REQ{{because 'sizeof(HasValue<false>) > 2' (1 > 2) evaluated to false}} |
| // expected-note@#TRAILING_REQ_VAL{{and 'HasValue<false>::value' evaluated to false}} |
| } |