xref: /llvm-project/clang/test/SemaTemplate/pr52970.cpp (revision 12cb1cb3720de8d164196010123ce1a8901d8122)
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)22 constexpr auto f(T t) -> decltype((t.a.b, true)) { return true; }
f(...)23 constexpr 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)47 constexpr auto f(T t) -> decltype((t.begin(), true)) { return true; }
f(...)48 constexpr 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