1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s 2 // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s 3 // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s 4 // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify=cxx20 %s 5 // expected-no-diagnostics 6 7 struct Incomplete; 8 template <class T> struct Holder { T t; }; 9 10 namespace DotFollowingFunctionName { 11 struct Good { 12 struct Nested { 13 int b; 14 } a; 15 }; 16 17 struct Bad { 18 Holder<Incomplete> a(); 19 }; 20 21 template <class T> f(T t)22constexpr auto f(T t) -> decltype((t.a.b, true)) { return true; } f(...)23constexpr bool f(...) { return false; } 24 25 static_assert(DotFollowingFunctionName::f(Good{}), ""); 26 static_assert(!DotFollowingFunctionName::f(Bad{}), ""); 27 28 #if __cplusplus >= 202002L 29 template <class T> 30 concept C = requires(T t) { t.a.b; }; 31 // cxx20-note@-1 {{because 't.a.b' would be invalid: reference to non-static member function must be called}} 32 33 static_assert(C<Good>); 34 static_assert(!C<Bad>); 35 static_assert(C<Bad>); // cxx20-error {{static assertion failed}} 36 // cxx20-note@-1 {{because 'Bad' does not satisfy 'C'}} 37 #endif 38 } // namespace DotFollowingFunctionName 39 40 namespace DotFollowingPointer { 41 struct Good { 42 int begin(); 43 }; 44 using Bad = Holder<Incomplete> *; 45 46 template <class T> f(T t)47constexpr auto f(T t) -> decltype((t.begin(), true)) { return true; } f(...)48constexpr bool f(...) { return false; } 49 50 static_assert(DotFollowingPointer::f(Good{}), ""); 51 static_assert(!DotFollowingPointer::f(Bad{}), ""); 52 53 #if __cplusplus >= 202002L 54 template <class T> 55 concept C = requires(T t) { t.begin(); }; 56 // cxx20-note@-1 {{because 't.begin()' would be invalid: member reference type 'Holder<Incomplete> *' is a pointer}} 57 58 static_assert(C<Good>); 59 static_assert(!C<Bad>); 60 static_assert(C<Bad>); // cxx20-error {{static assertion failed}} 61 // cxx20-note@-1 {{because 'Bad' (aka 'Holder<Incomplete> *') does not satisfy 'C'}} 62 #endif 63 } // namespace DotFollowingPointer 64