Clang Project

clang_source_code/test/Sema/vector-cast.c
1// RUN: %clang_cc1 -fsyntax-only %s -verify -Wvector-conversion
2
3typedef long long t1 __attribute__ ((vector_size (8)));
4typedef char t2 __attribute__ ((vector_size (16)));
5typedef float t3 __attribute__ ((vector_size (16)));
6typedef short s2 __attribute__ ((vector_size(4)));
7
8typedef enum { Evalue = 0x10000 } E;
9
10void f()
11{  
12  t1 v1;
13  t2 v2;
14  t3 v3;
15  s2 v4;
16  E e;
17
18  e = (E)v4;
19  v4 = (s2)e;
20  
21  v2 = (t2)v1; // expected-error {{invalid conversion between vector type \
22't2' (vector of 16 'char' values) and 't1' (vector of 1 'long long' value) of different size}}
23  v1 = (t1)v2; // expected-error {{invalid conversion between vector type \
24't1' (vector of 1 'long long' value) and 't2' (vector of 16 'char' values) of different size}}
25  v3 = (t3)v2;
26  
27  v1 = (t1)(char *)10; // expected-error {{invalid conversion between vector \
28type 't1' (vector of 1 'long long' value) and scalar type 'char *'}}
29  v1 = (t1)(long long)10;
30  v1 = (t1)(short)10; // expected-error {{invalid conversion between vector \
31type 't1' (vector of 1 'long long' value) and integer type 'short' of different size}}
32  
33  long long r1 = (long long)v1;
34  short r2 = (short)v1; // expected-error {{invalid conversion between vector \
35type 't1' (vector of 1 'long long' value) and integer type 'short' of different size}}
36  char *r3 = (char *)v1; // expected-error {{invalid conversion between vector\
37 type 't1' (vector of 1 'long long' value) and scalar type 'char *'}}
38}
39
40
41void f2(t2 X); // expected-note{{passing argument to parameter 'X' here}}
42
43void f3(t3 Y) {
44  f2(Y);  // expected-warning {{incompatible vector types passing 't3' (vector of 4 'float' values) to parameter of type 't2' (vector of 16 'char' values)}}
45}
46
47typedef float float2 __attribute__ ((vector_size (8)));
48typedef __attribute__((vector_size(8))) double float64x1_t;
49typedef __attribute__((vector_size(16))) double float64x2_t;
50float64x1_t vget_low_f64(float64x2_t __p0);
51typedef float float16 __attribute__((__vector_size__(16)));
52typedef signed int vSInt32 __attribute__((__vector_size__(16)));
53typedef unsigned int vUInt32 __attribute__((__vector_size__(16)));
54
55void f4() {
56  float2 f2;
57  double d, a, b, c;
58  float64x2_t v = {0.0, 1.0};
59  f2 += d; // expected-error {{cannot convert between scalar type 'double' and vector type 'float2' (vector of 2 'float' values) as implicit conversion would cause truncation}}
60  d += f2; // expected-error {{assigning to 'double' from incompatible type 'float2' (vector of 2 'float' values)}}
61  a = 3.0 + vget_low_f64(v);
62  b = vget_low_f64(v) + 3.0;
63  c = vget_low_f64(v);
64  c -= vget_low_f64(v);
65  // LAX conversions between scalar and vector types require same size and one element sized vectors.
66  d = f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
67  d = d + f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
68}
69
70// rdar://15931426
71// Don't permit a lax conversion to and from a pointer type.
72typedef short short_sizeof_pointer __attribute__((vector_size(sizeof(void*))));
73void f5() {
74  short_sizeof_pointer v;
75  void *ptr;
76  v = ptr; // expected-error-re {{assigning to 'short_sizeof_pointer' (vector of {{[0-9]+}} 'short' values) from incompatible type 'void *'}}
77  ptr = v; // expected-error {{assigning to 'void *' from incompatible type 'short_sizeof_pointer'}}
78}
79
80void f6(vSInt32 a0) {
81  vUInt32 counter = (float16){0.0f, 0.0f, 0.0f, 0.0f}; // expected-warning {{incompatible vector types initializing 'vUInt32' (vector of 4 'unsigned int' values) with an expression of type 'float16' (vector of 4 'float' values)}}
82  counter -= a0;
83}
84