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
8 template <class T
> struct Holder
{ T t
; };
10 namespace DotFollowingFunctionName
{
18 Holder
<Incomplete
> a();
22 constexpr auto f(T t
) -> decltype((t
.a
.b
, true)) { return true; }
23 constexpr bool f(...) { return false; }
25 static_assert(DotFollowingFunctionName::f(Good
{}), "");
26 static_assert(!DotFollowingFunctionName::f(Bad
{}), "");
28 #if __cplusplus >= 202002L
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}}
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'}}
38 } // namespace DotFollowingFunctionName
40 namespace DotFollowingPointer
{
44 using Bad
= Holder
<Incomplete
> *;
47 constexpr auto f(T t
) -> decltype((t
.begin(), true)) { return true; }
48 constexpr bool f(...) { return false; }
50 static_assert(DotFollowingPointer::f(Good
{}), "");
51 static_assert(!DotFollowingPointer::f(Bad
{}), "");
53 #if __cplusplus >= 202002L
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}}
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'}}
63 } // namespace DotFollowingPointer