xref: /llvm-project/clang/test/SemaCXX/sugared-auto.cpp (revision 9d739e54f4506bf9bd220c5d65f710b86a39f6d5)
1 // RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
2 // RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
3 
4 namespace std {
5 template<typename T> struct initializer_list {
6   const T *begin, *end;
7   initializer_list();
8 };
9 } // namespace std
10 
11 enum class N {};
12 
13 using Animal = int;
14 
15 using AnimalPtr = Animal *;
16 
17 using Man = Animal;
18 using Dog = Animal;
19 
20 using ManPtr = Man *;
21 using DogPtr = Dog *;
22 
23 using SocratesPtr = ManPtr;
24 
25 using ConstMan = const Man;
26 using ConstDog = const Dog;
27 
28 using Virus = void;
29 using SARS = Virus;
30 using Ebola = Virus;
31 
32 using Bacteria = float;
33 using Bacilli = Bacteria;
34 using Vibrio = Bacteria;
35 
36 struct Plant;
37 using Gymnosperm = Plant;
38 using Angiosperm = Plant;
39 
40 namespace variable {
41 
42 auto x1 = Animal();
43 N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
44 
45 auto x2 = AnimalPtr();
46 N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
47 
48 auto *x3 = AnimalPtr();
49 N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
50 
51 // Each variable deduces separately.
52 auto x4 = Man(), x5 = Dog();
53 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
54 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
55 
56 auto x6 = { Man(), Dog() };
57 N t6 = x6; // expected-error {{from 'std::initializer_list<Animal>' (aka 'initializer_list<int>')}}
58 
59 } // namespace variable
60 
61 namespace function_basic {
62 
63 auto f1() { return Animal(); }
64 auto x1 = f1();
65 N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
66 
67 decltype(auto) f2() { return Animal(); }
68 auto x2 = f2();
69 N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
70 
71 auto x3 = [a = Animal()] { return a; }();
72 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
73 
74 } // namespace function_basic
75 
76 namespace function_multiple_basic {
77 
78 N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
79   if (true)
80     return Man();
81   return Dog();
82 }();
83 
84 N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
85   if (true)
86     return Man();
87   return Dog();
88 }();
89 
90 N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
91   if (true)
92     return Dog();
93   auto x = Man();
94   return x;
95 }();
96 
97 N t4 = [] { // expected-error {{rvalue of type 'int'}}
98   if (true)
99     return Dog();
100   return 1;
101 }();
102 
103 N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
104   if (true)
105     return Ebola();
106   return SARS();
107 }();
108 
109 N t6 = [] { // expected-error {{rvalue of type 'void'}}
110   if (true)
111     return SARS();
112   return;
113 }();
114 
115 N t7 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
116   if (true)
117     return Ebola();
118   return SARS{};
119 }();
120 
121 } // namespace function_multiple_basic
122 
123 #define TEST_AUTO(X, A, B) \
124   static_assert(__is_same(A, B), ""); \
125   auto X(A a, B b) {       \
126     if (0)                 \
127       return a;            \
128     if (0)                 \
129       return b;            \
130     return N();            \
131   }
132 #define TEST_DAUTO(X, A, B)     \
133   static_assert(__is_same(A, B), ""); \
134   decltype(auto) X(A a, B b) {  \
135     if (0)                      \
136       return static_cast<A>(a); \
137     if (0)                      \
138       return static_cast<B>(b); \
139     return N();                 \
140   }
141 
142 namespace misc {
143 
144 TEST_AUTO(t1, ManPtr, DogPtr)      // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
145 TEST_AUTO(t2, ManPtr, int *)       // expected-error {{but deduced as 'int *'}}
146 TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
147 
148 TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
149 
150 using block_man = void (^)(Man);
151 using block_dog = void (^)(Dog);
152 TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
153 
154 #if __cplusplus >= 201500
155 using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
156 using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
157 TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
158 
159 using fp3 = SARS (*)() throw(Man);
160 using fp4 = Ebola (*)() throw(Vibrio);
161 auto t7(fp3 a, fp4 b) {
162   if (false)
163     return true ? a : b;
164   if (false)
165     return a;
166   return N(); // expected-error {{but deduced as 'Virus (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
167 }
168 #endif
169 
170 using fp5 = void (*)(const Man);
171 using fp6 = void (*)(Dog);
172 TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(Animal)' (aka 'void (*)(int)')}}
173 
174 using fp7 = void (*)(ConstMan);
175 using fp8 = void (*)(ConstDog);
176 TEST_AUTO(t9, fp7, fp8); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
177 
178 using fp9 = void (*)(ConstMan);
179 using fp10 = void (*)(const Dog);
180 TEST_AUTO(t10, fp9, fp10); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
181 
182 using fp11 = void (*)(__strong block_man);
183 using fp12 = void (*)(__weak block_dog);
184 TEST_AUTO(t11, fp11, fp12); // expected-error {{but deduced as 'void (*)(void (^)(Animal))'}}
185 
186 TEST_AUTO(t12, Man Angiosperm::*, Dog Gymnosperm::*) // expected-error {{but deduced as 'Animal Plant::*'}}
187 
188 TEST_DAUTO(t13, const Man &, const Dog &) // expected-error {{but deduced as 'const Animal &' (aka 'const int &')}}
189 
190 TEST_DAUTO(t14, Man &&, Dog &&) // expected-error {{but deduced as 'Animal &&' (aka 'int &&')}}
191 
192 using matrix_man = Man __attribute__((matrix_type(4, 4)));
193 using matrix_dog = Dog __attribute__((matrix_type(4, 4)));
194 TEST_AUTO(t15, matrix_man, matrix_dog) // expected-error {{but deduced as 'Animal __attribute__((matrix_type(4, 4)))'}}
195 
196 using vector_man = Man __attribute__((vector_size(4)));
197 using vector_dog = Dog __attribute__((vector_size(4)));
198 TEST_AUTO(t16, vector_man, vector_dog) // expected-error {{but deduced as '__attribute__((__vector_size__(1 * sizeof(Animal)))) Animal' (vector of 1 'Animal' value)}}
199 
200 using ext_vector_man = Man __attribute__((ext_vector_type(4)));
201 using ext_vector_dog = Dog __attribute__((ext_vector_type(4)));
202 TEST_AUTO(t17, ext_vector_man, ext_vector_dog) // expected-error {{but deduced as 'Animal __attribute__((ext_vector_type(4)))' (vector of 4 'Animal' values)}}
203 
204 using TwoDogs = Dog[2];
205 using ConstTwoDogsPtr = const TwoDogs*;
206 using ConstTwoMenPtr = const Man(*)[2];
207 TEST_AUTO(t18, ConstTwoDogsPtr, ConstTwoMenPtr); // expected-error {{but deduced as 'const Animal (*)[2]' (aka 'const int (*)[2]')}}
208 
209 } // namespace misc
210 
211 namespace exception_spec {
212 
213 void none();
214 void dyn_none() throw();
215 void dyn() throw(int);
216 void ms_any() throw(...);
217 void __declspec(nothrow) nothrow();
218 void noexcept_basic() noexcept;
219 void noexcept_true() noexcept(true);
220 void noexcept_false() noexcept(false);
221 
222 #if __cplusplus < 201500
223 TEST_AUTO(t1, decltype(&noexcept_false), decltype(&noexcept_true)) // expected-error {{but deduced as 'void (*)() noexcept(false)'}}
224 TEST_AUTO(t2, decltype(&noexcept_basic), decltype(&noexcept_true)) // expected-error {{but deduced as 'void (*)() noexcept(true)'}}
225 TEST_AUTO(t3, decltype(&none), decltype(&ms_any)) // expected-error {{but deduced as 'void (*)()'}}
226 TEST_AUTO(t4, decltype(&noexcept_false), decltype(&ms_any)) // expected-error {{but deduced as 'void (*)() throw(...)'}}
227 TEST_AUTO(t5, decltype(&nothrow), decltype(&noexcept_false)) // expected-error {{but deduced as 'void (*)() noexcept(false)'}}
228 TEST_AUTO(t6, decltype(&dyn_none), decltype(&nothrow)) // expected-error {{but deduced as 'void (*)() throw()'}}
229 TEST_AUTO(t7, decltype(&noexcept_true), decltype(&dyn)) // expected-error {{but deduced as 'void (*)() throw(int)'}}
230 #endif
231 } // namespace exception_spec
232 
233 namespace non_deduced {
234   void f();
235   void g();
236   void g(int);
237   auto h() {
238     if (false) return f;
239     return g;
240     // expected-error@-1 {{returned value of type '<overloaded function type>'}}
241   }
242 } // namespace non_deduced
243