92 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2c %s2 3template <typename> struct TS; // #template4 5struct Errors {6 friend int, int;7 friend int, long, char;8 9 // We simply diagnose and ignore the '...' here.10 friend float...; // expected-error {{pack expansion does not contain any unexpanded parameter packs}}11 12 friend short..., unsigned, unsigned short...; // expected-error 2 {{pack expansion does not contain any unexpanded parameter packs}}13 14 template <typename>15 friend struct TS, int; // expected-error {{a friend declaration that befriends a template must contain exactly one type-specifier}}16 17 double friend; // expected-error {{'friend' must appear first in a non-function declaration}}18 double friend, double; // expected-error {{expected member name or ';' after declaration specifiers}}19};20 21template <typename>22struct C { template<class T> class Nested; };23 24template <typename, typename>25struct D { template<class T> class Nested; };26 27template <bool>28struct E { template<class T> class Nested; };29 30template<class... Ts> // expected-note {{template parameter is declared here}}31struct VS {32 friend Ts...;33 34 friend class Ts...; // expected-error {{declaration of 'Ts' shadows template parameter}}35 // expected-error@-1 {{pack expansion does not contain any unexpanded parameter packs}}36 37 // TODO: Fix-it hint to insert '...'.38 friend Ts; // expected-error {{friend declaration contains unexpanded parameter pack}}39 40 template<class... Us>41 friend Us...; // expected-error {{friend type templates must use an elaborated type}}42 43 template<class... Us> // expected-note {{is declared here}}44 friend class Us...; // expected-error {{declaration of 'Us' shadows template parameter}}45 46 template<class U>47 friend class C<Ts>::template Nested<U>...; // expected-error {{cannot specialize a dependent template}}48 49 template<class... Us>50 friend class C<Ts...>::template Nested<Us>...; // expected-error {{cannot specialize a dependent template}}51 52 // Nonsense (see CWG 2917).53 template<class... Us>54 friend class C<Us>::Nested...; // expected-error {{friend declaration expands pack 'Us' that is declared it its own template parameter list}}55 56 template<bool... Bs>57 friend class E<Bs>::Nested...; // expected-error {{friend declaration expands pack 'Bs' that is declared it its own template parameter list}}58 59 // FIXME: Both of these should be valid, but we can't handle these at60 // the moment because the NNS is dependent.61 template<class ...T>62 friend class TS<Ts>::Nested...; // expected-warning {{dependent nested name specifier 'TS<Ts>' for friend template declaration is not supported; ignoring this friend declaration}}63 64 template<class T>65 friend class D<T, Ts>::Nested...; // expected-warning {{dependent nested name specifier 'D<T, Ts>' for friend class declaration is not supported; turning off access control for 'VS'}}66};67 68namespace length_mismatch {69struct A {70 template <typename...>71 struct Nested {72 struct Foo{};73 };74};75template <typename ...Ts>76struct S {77 template <typename ...Us>78 struct T {79 // expected-error@+2 {{pack expansion contains parameter packs 'Ts' and 'Us' that have different lengths (1 vs. 2)}}80 // expected-error@+1 {{pack expansion contains parameter packs 'Ts' and 'Us' that have different lengths (2 vs. 1)}}81 friend class Ts::template Nested<Us>::Foo...;82 };83};84 85void f() {86 S<A>::T<int> s;87 S<A, A>::T<int, long> s2;88 S<A>::T<int, long> s3; // expected-note {{in instantiation of}}89 S<A, A>::T<int> s4; // expected-note {{in instantiation of}}90}91}92