1 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=c++11 %s
4 // RUN: %clang_cc1 -flax-vector-conversions=integer -triple x86_64-apple-darwin10 -fsyntax-only -verify %s -DNO_LAX_FLOAT
5 // RUN: %clang_cc1 -flax-vector-conversions=none -triple x86_64-apple-darwin10 -fsyntax-only -verify %s -DNO_LAX_FLOAT -DNO_LAX_INT
7 typedef char char16
__attribute__ ((__vector_size__ (16)));
8 typedef long long longlong16
__attribute__ ((__vector_size__ (16)));
9 typedef char char16_e
__attribute__ ((__ext_vector_type__ (16)));
10 typedef long long longlong16_e
__attribute__ ((__ext_vector_type__ (2)));
12 // Test overloading and function calls with vector types.
13 void f0(char16
); // expected-note 0+{{candidate}}
15 void f0_test(char16 c16
, longlong16 ll16
, char16_e c16e
, longlong16_e ll16e
) {
19 // expected-error@-2 {{no matching function}}
24 // expected-error@-2 {{no matching function}}
29 float &f1(longlong16
);
31 void f1_test(char16 c16
, longlong16 ll16
, char16_e c16e
, longlong16_e ll16e
) {
33 float &fr1
= f1(ll16
);
35 float &fr2
= f1(ll16e
);
38 void f2(char16_e
); // expected-note 0+{{candidate}}
40 void f2_test(char16 c16
, longlong16 ll16
, char16_e c16e
, longlong16_e ll16e
) {
44 // expected-error@-2 {{no matching function}}
47 f2(ll16e
); // expected-error{{no matching function}}
52 // Test the conditional operator with vector types.
53 void conditional(bool Cond
, char16 c16
, longlong16 ll16
, char16_e c16e
,
55 // Conditional operators with the same type.
56 __typeof__(Cond
? c16
: c16
) *c16p1
= &c16
;
57 __typeof__(Cond
? ll16
: ll16
) *ll16p1
= &ll16
;
58 __typeof__(Cond
? c16e
: c16e
) *c16ep1
= &c16e
;
59 __typeof__(Cond
? ll16e
: ll16e
) *ll16ep1
= &ll16e
;
61 // Conditional operators with similar types.
62 __typeof__(Cond
? c16
: c16e
) *c16ep2
= &c16e
;
63 __typeof__(Cond
? c16e
: c16
) *c16ep3
= &c16e
;
64 __typeof__(Cond
? ll16
: ll16e
) *ll16ep2
= &ll16e
;
65 __typeof__(Cond
? ll16e
: ll16
) *ll16ep3
= &ll16e
;
67 // Conditional operators with compatible types under -flax-vector-conversions (default)
68 (void)(Cond
? c16
: ll16
);
69 (void)(Cond
? ll16e
: c16e
);
70 (void)(Cond
? ll16e
: c16
);
72 // expected-error@-4 {{cannot convert}}
73 // expected-error@-4 {{cannot convert}}
74 // expected-error@-4 {{cannot convert}}
78 // Test C++ cast'ing of vector types.
79 void casts(longlong16 ll16
, longlong16_e ll16e
) {
83 (void)(longlong16
)ll16
;
84 (void)(longlong16_e
)ll16
;
86 (void)(char16_e
)ll16e
;
87 (void)(longlong16
)ll16e
;
88 (void)(longlong16_e
)ll16e
;
90 // Function-style casts.
93 (void)longlong16(ll16
);
94 (void)longlong16_e(ll16
);
96 (void)char16_e(ll16e
);
97 (void)longlong16(ll16e
);
98 (void)longlong16_e(ll16e
);
101 (void)static_cast<char16
>(ll16
);
102 (void)static_cast<char16_e
>(ll16
);
104 // expected-error@-3 {{not allowed}}
105 // expected-error@-3 {{not allowed}}
107 (void)static_cast<longlong16
>(ll16
);
108 (void)static_cast<longlong16_e
>(ll16
);
109 (void)static_cast<char16
>(ll16e
);
111 // expected-error@-2 {{not allowed}}
113 (void)static_cast<char16_e
>(ll16e
); // expected-error{{static_cast from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) is not allowed}}
114 (void)static_cast<longlong16
>(ll16e
);
115 (void)static_cast<longlong16_e
>(ll16e
);
118 (void)reinterpret_cast<char16
>(ll16
);
119 (void)reinterpret_cast<char16_e
>(ll16
);
120 (void)reinterpret_cast<longlong16
>(ll16
);
121 (void)reinterpret_cast<longlong16_e
>(ll16
);
122 (void)reinterpret_cast<char16
>(ll16e
);
123 (void)reinterpret_cast<char16_e
>(ll16e
);
124 (void)reinterpret_cast<longlong16
>(ll16e
);
125 (void)reinterpret_cast<longlong16_e
>(ll16e
);
129 struct convertible_to
{ // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable}}
130 #if __cplusplus >= 201103L // C++11 or later
131 // expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
136 void test_implicit_conversions(bool Cond
, char16 c16
, longlong16 ll16
,
137 char16_e c16e
, longlong16_e ll16e
,
138 convertible_to
<char16
> to_c16
,
139 convertible_to
<longlong16
> to_ll16
,
140 convertible_to
<char16_e
> to_c16e
,
141 convertible_to
<longlong16_e
> to_ll16e
,
142 convertible_to
<char16
&> rto_c16
,
143 convertible_to
<char16_e
&> rto_c16e
) {
147 // expected-error@-2 {{no matching function}}
152 // expected-error@-2 {{no matching function}}
157 // expected-error@-2 {{no matching function}}
160 f2(to_ll16e
); // expected-error{{no matching function}}
163 (void)(c16
== to_c16
);
167 (void)(to_c16
== to_c16e
);
168 (void)(to_c16
!= to_c16e
);
169 (void)(to_c16
< to_c16e
);
170 (void)(to_c16
<= to_c16e
);
171 (void)(to_c16
> to_c16e
);
172 (void)(to_c16
>= to_c16e
);
173 (void)(to_c16
+ to_c16
);
174 (void)(to_c16
- to_c16
);
175 (void)(to_c16
* to_c16
);
176 (void)(to_c16
/ to_c16
);
177 (void)(rto_c16
= to_c16
); // expected-error{{no viable overloaded '='}}
178 (void)(rto_c16
+= to_c16
);
179 (void)(rto_c16
-= to_c16
);
180 (void)(rto_c16
*= to_c16
);
181 (void)(rto_c16
/= to_c16
);
186 (void)(to_c16e
== to_c16e
);
187 (void)(to_c16e
!= to_c16e
);
188 (void)(to_c16e
< to_c16e
);
189 (void)(to_c16e
<= to_c16e
);
190 (void)(to_c16e
> to_c16e
);
191 (void)(to_c16e
>= to_c16e
);
192 (void)(to_c16e
+ to_c16
);
193 (void)(to_c16e
- to_c16
);
194 (void)(to_c16e
* to_c16
);
195 (void)(to_c16e
/ to_c16
);
196 (void)(rto_c16e
= to_c16
); // expected-error{{no viable overloaded '='}}
197 (void)(rto_c16e
+= to_c16
);
198 (void)(rto_c16e
-= to_c16
);
199 (void)(rto_c16e
*= to_c16
);
200 (void)(rto_c16e
/= to_c16
);
205 (void)(to_c16
== to_c16e
);
206 (void)(to_c16
!= to_c16e
);
207 (void)(to_c16
< to_c16e
);
208 (void)(to_c16
<= to_c16e
);
209 (void)(to_c16
> to_c16e
);
210 (void)(to_c16
>= to_c16e
);
211 (void)(to_c16
+ to_c16e
);
212 (void)(to_c16
- to_c16e
);
213 (void)(to_c16
* to_c16e
);
214 (void)(to_c16
/ to_c16e
);
215 (void)(rto_c16
= c16e
); // expected-error{{no viable overloaded '='}}
216 (void)(rto_c16
+= to_c16e
);
217 (void)(rto_c16
-= to_c16e
);
218 (void)(rto_c16
*= to_c16e
);
219 (void)(rto_c16
/= to_c16e
);
221 (void)(Cond
? to_c16
: to_c16e
);
222 (void)(Cond
? to_ll16e
: to_ll16
);
224 // These 2 are convertible with -flax-vector-conversions (default)
225 (void)(Cond
? to_c16
: to_ll16
);
226 (void)(Cond
? to_c16e
: to_ll16e
);
228 // expected-error@-3 {{cannot convert}}
229 // expected-error@-3 {{cannot convert}}
233 typedef float fltx2
__attribute__((__vector_size__(8)));
234 typedef float fltx4
__attribute__((__vector_size__(16)));
235 typedef double dblx2
__attribute__((__vector_size__(16)));
236 typedef double dblx4
__attribute__((__vector_size__(32)));
238 void accept_fltx2(fltx2
); // expected-note{{candidate function not viable: no known conversion from 'double' to 'fltx2' (vector of 2 'float' values) for 1st argument}}
239 void accept_fltx4(fltx4
);
240 void accept_dblx2(dblx2
);
242 // expected-note@-3 {{no known conversion}}
243 // expected-note@-3 {{no known conversion}}
245 void accept_dblx4(dblx4
);
246 void accept_bool(bool); // expected-note{{candidate function not viable: no known conversion from 'fltx2' (vector of 2 'float' values) to 'bool' for 1st argument}}
248 void test(fltx2 fltx2_val
, fltx4 fltx4_val
, dblx2 dblx2_val
, dblx4 dblx4_val
) {
250 accept_fltx2(fltx2_val
);
251 accept_fltx4(fltx4_val
);
252 accept_dblx2(dblx2_val
);
253 accept_dblx4(dblx4_val
);
255 // Same-size conversions
256 accept_fltx4(dblx2_val
);
257 accept_dblx2(fltx4_val
);
259 // expected-error@-3 {{no matching function}}
260 // expected-error@-3 {{no matching function}}
263 // Conversion to bool.
264 accept_bool(fltx2_val
); // expected-error{{no matching function for call to 'accept_bool'}}
266 // Scalar-to-vector conversions.
267 accept_fltx2(1.0); // expected-error{{no matching function for call to 'accept_fltx2'}}
270 typedef int intx4
__attribute__((__vector_size__(16)));
271 typedef int inte4
__attribute__((__ext_vector_type__(4)));
272 typedef float flte4
__attribute__((__ext_vector_type__(4)));
274 void test_mixed_vector_types(fltx4 f
, intx4 n
, flte4 g
, inte4 m
) {
319 template<typename T
> void test_pseudo_dtor_tmpl(T
*ptr
) {
324 void test_pseudo_dtor(fltx4
*f
) {
327 test_pseudo_dtor_tmpl(f
);
331 typedef __attribute__((ext_vector_type(4))) int vi4
;
332 const int &reference_to_vec_element
= vi4(1).x
;
335 typedef bool bad
__attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}}
337 namespace Templates
{
338 template <typename Elt
, unsigned long long Size
>
339 struct TemplateVectorType
{
340 typedef Elt
__attribute__((__vector_size__(Size
))) type
; // #1
343 template <int N
, typename T
>
345 typedef T
__attribute__((vector_size(N
* sizeof(T
)))) type
;
346 typedef T
__attribute__((vector_size(0x1000000000))) type2
; // #2
347 typedef T
__attribute__((vector_size(3))) type3
; // #3
351 const TemplateVectorType
<float, 32>::type Works
= {};
352 const TemplateVectorType
<int, 32>::type Works2
= {};
353 // expected-error@#1 {{invalid vector element type 'bool'}}
354 // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<bool, 32>' requested here}}
355 const TemplateVectorType
<bool, 32>::type NoBool
= {};
356 // expected-error@#1 {{invalid vector element type 'int __attribute__((ext_vector_type(4)))' (vector of 4 'int' values)}}
357 // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int __attribute__((ext_vector_type(4))), 32>' requested here}}
358 const TemplateVectorType
<vi4
, 32>::type NoComplex
= {};
359 // expected-error@#1 {{vector size not an integral multiple of component size}}
360 // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 33>' requested here}}
361 const TemplateVectorType
<int, 33>::type BadSize
= {};
362 const TemplateVectorType
<int, 3200>::type Large
= {};
363 // expected-error@#1 {{vector size too large}}
364 // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 68719476736>' requested here}}
365 const TemplateVectorType
<int, 0x1000000000>::type TooLarge
= {};
366 // expected-error@#1 {{zero vector size}}
367 // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 0>' requested here}}
368 const TemplateVectorType
<int, 0>::type Zero
= {};
370 // expected-error@#2 {{vector size too large}}
371 // expected-error@#3 {{vector size not an integral multiple of component size}}
372 // expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, int>' requested here}}
373 const PR15730
<8, int>::type PR15730_1
= {};
374 // expected-error@#2 {{vector size too large}}
375 // expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, char>' requested here}}
376 const PR15730
<8, char>::type2 PR15730_2
= {};
379 } // namespace Templates
381 typedef int inte2
__attribute__((__ext_vector_type__(2)));
383 void test_vector_literal(inte4 res
) {
384 inte2 a
= (inte2
)(1, 2); //expected-warning{{left operand of comma operator has no effect}}
385 inte4 b
= (inte4
)(a
, a
); //expected-error{{C-style cast from vector 'inte2' (vector of 2 'int' values) to vector 'inte4' (vector of 4 'int' values) of different size}} //expected-warning{{left operand of comma operator has no effect}}
388 typedef __attribute__((__ext_vector_type__(4))) float vector_float4
;
389 typedef __attribute__((__ext_vector_type__(4))) int vector_int4
;
391 namespace swizzle_template_confusion
{
392 template<typename T
> struct xyzw
{};
393 vector_int4
foo123(vector_float4
&A
, vector_float4
&B
) {
394 return A
.xyzw
< B
.x
&& B
.y
> A
.y
; // OK, not a template-id
398 namespace swizzle_typo_correction
{
399 template<typename T
> struct xyzv
{};
400 vector_int4
foo123(vector_float4
&A
, vector_float4
&B
) {
401 return A
.xyzw
< B
.x
&& B
.y
> A
.y
; // OK, not a typo for 'xyzv'
406 typedef float float4
__attribute__((vector_size(16)));
408 // In this example, 'k' is value dependent. PR45299 reported that this asserted
409 // because of that, since the truncation check attempted to constant evaluate k,
410 // which it could not do because it is dependent.
411 template <typename T
>
412 struct NormalMember
{
419 #if __cplusplus >= 201103L
420 // This should not diagnose, since the constant evaluator (during instantiation)
421 // can tell that this isn't a truncation.
422 template <typename T
>
423 struct ConstantValueNoDiag
{
427 static constexpr double k
= 1;
429 template <typename T
, int N
>
430 struct ConstantValueNoDiagDependentValue
{
434 static constexpr double k
= N
;
437 // The following two both diagnose because they cause a truncation. Test both
438 // the dependent type and non-dependent type versions.
439 template <typename T
>
442 // expected-error@+1{{as implicit conversion would cause truncation}}
445 static constexpr double k
= 1340282346638528859811704183484516925443.000000;
447 template <typename T
, int N
>
448 struct DiagTruncDependentValue
{
450 // expected-error@+1{{as implicit conversion would cause truncation}}
453 static constexpr double k
= N
+ 1340282346638528859811704183484516925443.000000;
455 template <typename T
>
456 struct DiagTruncDependentType
{
458 // expected-error@+1{{as implicit conversion would cause truncation}}
461 static constexpr T k
= 1340282346638528859811704183484516925443.000000;
464 template <typename T
>
469 // Ensure this no longer asserts.
470 template <typename T
>
471 struct PR45298Consumer
{
473 return (float)s
.k1
* x
;
478 #endif // __cplusplus >= 201103L
482 NormalMember
<double>().f(theFloat4
);
483 #if __cplusplus >= 201103L
484 ConstantValueNoDiag
<double>().f(theFloat4
);
485 ConstantValueNoDiagDependentValue
<double, 1>().f(theFloat4
);
486 DiagTrunc
<double>().f(theFloat4
);
487 // expected-note@+1{{in instantiation of member function}}
488 DiagTruncDependentValue
<double, 0>().f(theFloat4
);
489 // expected-note@+1{{in instantiation of member function}}
490 DiagTruncDependentType
<double>().f(theFloat4
);
491 PR45298Consumer
<double>().f(theFloat4
);
492 #endif // __cplusplus >= 201103L
496 namespace rdar60092165
{
497 template <class T
> void f() {
498 typedef T first_type
__attribute__((vector_size(sizeof(T
) * 4)));
499 typedef T second_type
__attribute__((vector_size(sizeof(T
) * 4)));
506 enum E
{ Value
= 15 };
509 c
&Value
; // expected-error{{cannot convert between scalar type 'PR45780::E' and vector type 'char16'}}
510 c
== Value
; // expected-error{{cannot convert between scalar type 'PR45780::E' and vector type 'char16'}}
511 e
| c
; // expected-error{{cannot convert between scalar type 'E' and vector type 'char16'}}
512 e
!= c
; // expected-error{{cannot convert between scalar type 'E' and vector type 'char16'}}
515 } // namespace PR45780
518 // The below used to cause an OOM error, or an assert, make sure it is still
520 int (__attribute__((vector_size(16))) a
);
522 template <typename T
, int I
>
524 T (__attribute__((vector_size(16))) a
);
525 int (__attribute__((vector_size(I
))) b
);
526 T (__attribute__((vector_size(I
))) c
);
532 } // namespace PR48540