xref: /llvm-project/clang/test/SemaTemplate/find-unexpanded-packs.cpp (revision f1b0a4fc540f986372f09768c325d505b75b414d)
1 // RUN: %clang_cc1 -verify %s -std=c++17 -Wno-unused
2 
PackInsideTypedefDeclaration()3 template<typename ...Ts> void PackInsideTypedefDeclaration() {
4   ([] {
5     typedef Ts Type;
6     (void)Type();
7   }(), ...);
8 }
9 template void PackInsideTypedefDeclaration<>();
10 template void PackInsideTypedefDeclaration<int>();
11 template void PackInsideTypedefDeclaration<int, float>();
12 
PackInsideTypedefDeclarationInvalid()13 template<typename ...Ts> void PackInsideTypedefDeclarationInvalid() {
14   [] { // expected-error {{contains unexpanded parameter pack 'Ts'}}
15     typedef Ts Type;
16     (void)Type();
17   };
18 
19   ([] {
20     typedef Ts Type;
21     // A reference to a typedef containing an unexpanded pack does not
22     // itself contain an unexpanded pack.
23     f(Type()...); // expected-error {{does not contain any unexpanded}}
24   }, ...);
25 }
26 
27 
PackInsideAliasDeclaration()28 template<typename ...Ts> void PackInsideAliasDeclaration() {
29   ([] {
30     using Type = Ts;
31     (void)Type();
32   }(), ...);
33 }
34 template void PackInsideAliasDeclaration<>();
35 template void PackInsideAliasDeclaration<int>();
36 template void PackInsideAliasDeclaration<int, float>();
37 
PackInsideAliasDeclarationInvalid()38 template<typename ...Ts> void PackInsideAliasDeclarationInvalid() {
39   [] { // expected-error {{contains unexpanded parameter pack 'Ts'}}
40     using Type = Ts;
41     (void)Type();
42   };
43   ([] {
44     using Type = Ts;
45     // A reference to an alias containing an unexpanded pack does not
46     // itself contain an unexpanded pack.
47     f(Type()...); // expected-error {{does not contain any unexpanded}}
48   }, ...);
49 }
50 
51 
PackInsideUsingDeclaration()52 template<typename ...Ts> void PackInsideUsingDeclaration() {
53   ([] {
54     struct A {
55       using Type = Ts;
56     };
57     struct B : A {
58       using typename A::Type;
59     };
60     (void)typename B::Type();
61   }(), ...);
62 }
63 template void PackInsideUsingDeclaration<>();
64 template void PackInsideUsingDeclaration<int>();
65 template void PackInsideUsingDeclaration<int, float>();
66 
PackInsideUsingDeclarationInvalid()67 template<typename ...Ts> void PackInsideUsingDeclarationInvalid() {
68   ([] {
69     struct A {
70       using Type = Ts;
71     };
72     struct B : A {
73       using typename A::Type...; // expected-error {{does not contain any unexpanded}}
74     };
75   }(), ...);
76 }
77 
78 
PackInsideVarDeclaration()79 template<typename ...Ts> void PackInsideVarDeclaration() {
80   ([] {
81     Ts ts;
82     (void)ts;
83   }, ...);
84 }
85 template void PackInsideVarDeclaration<>();
86 template void PackInsideVarDeclaration<int>();
87 template void PackInsideVarDeclaration<int, float>();
88 
PackInsideVarDeclarationInvalid()89 template<typename ...Ts> void PackInsideVarDeclarationInvalid() {
90   [] { // expected-error {{contains unexpanded parameter pack 'Ts'}}
91     Ts ts;
92     (void)ts;
93   };
94 }
95 
96 
PackInsideFunctionDeclaration()97 template<typename ...Ts> void PackInsideFunctionDeclaration() {
98   ([] {
99     Ts ts(Ts);
100     ts({});
101   }, ...);
102 }
103 template void PackInsideFunctionDeclaration<>();
104 template void PackInsideFunctionDeclaration<int>();
105 template void PackInsideFunctionDeclaration<int, float>();
106 
PackInsideFunctionDeclarationInvalid()107 template<typename ...Ts> void PackInsideFunctionDeclarationInvalid() {
108   [] { // expected-error {{contains unexpanded parameter pack 'Ts'}}
109     Ts ts(Ts);
110     ts({});
111   };
112 }
113 
114 
PackInsideLocalClass()115 template<typename ...Ts> void PackInsideLocalClass() {
116   ([] {
117     class Local {
118       Ts ts;
119     };
120     Local l;
121   }, ...);
122 }
123 template void PackInsideLocalClass<>();
124 template void PackInsideLocalClass<int>();
125 template void PackInsideLocalClass<int, float>();
126 
PackInsideLocalClassInvalid()127 template<typename ...Ts> void PackInsideLocalClassInvalid() {
128   [] { // expected-error {{contains unexpanded parameter pack 'Ts'}}
129     class Local {
130       Ts ts;
131     };
132     Local l;
133   };
134 }
135 
136 template<typename T> using Int = int;
137 struct AClass {};
138 template<typename T> using Class = AClass;
HiddenPack()139 template<typename ...Ts> void HiddenPack() {
140   (Int<Ts>(), ...);
141   (Int<Ts>{}, ...);
142   (Class<Ts>(), ...);
143   (Class<Ts>{}, ...);
144 
145   ([] {
146    Int<Ts>();
147    }, ...);
148   ([] {
149    Int<Ts>{};
150    }, ...);
151   ([] {
152    Class<Ts>();
153    }, ...);
154   ([] {
155    Class<Ts>{};
156    }, ...);
157 }
158 template void HiddenPack<>();
159 template void HiddenPack<int>();
160 template void HiddenPack<int, float>();
161 
HiddenPackInvalid()162 template<typename ...Ts> void HiddenPackInvalid() {
163   Int<Ts>(); // expected-error {{unexpanded}}
164   Int<Ts>{}; // expected-error {{unexpanded}}
165   Class<Ts>(); // expected-error {{unexpanded}}
166   Class<Ts>{}; // expected-error {{unexpanded}}
167 }
168