xref: /llvm-project/clang/test/Sema/wasm-refs-and-tables.c (revision 84a3aadf0f2483dde0acfc4e79f2a075a5f35bd1)
1 // RUN: %clang_cc1 -fsyntax-only -verify=expected,conly -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
2 // RUN: %clang_cc1 -x c++ -std=c++17 -fsyntax-only -verify=expected,cpp -triple wasm32 -Wno-unused-value -target-feature +reference-types %s
3 
4 // Note: As WebAssembly references are sizeless types, we don't exhaustively
5 // test for cases covered by sizeless-1.c and similar tests.
6 
7 // Unlike standard sizeless types, reftype globals are supported.
8 __externref_t r1;
9 extern __externref_t r2;
10 static __externref_t r3;
11 
12 __externref_t *t1;               // expected-error {{pointer to WebAssembly reference type is not allowed}}
13 __externref_t **t2;              // expected-error {{pointer to WebAssembly reference type is not allowed}}
14 __externref_t ******t3;          // expected-error {{pointer to WebAssembly reference type is not allowed}}
15 static __externref_t t4[3];      // expected-error {{only zero-length WebAssembly tables are currently supported}}
16 static __externref_t t5[];       // expected-error {{only zero-length WebAssembly tables are currently supported}}
17 static __externref_t t6[] = {0}; // expected-error {{only zero-length WebAssembly tables are currently supported}}
18 __externref_t t7[0];             // expected-error {{WebAssembly table must be static}}
19 static __externref_t t8[0][0];   // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
20 static __externref_t (*t9)[0];   // expected-error {{cannot form a pointer to a WebAssembly table}}
21 
22 static __externref_t table[0];
23 static __externref_t other_table[0] = {};
24 static __externref_t another_table[] = {}; // expected-error {{only zero-length WebAssembly tables are currently supported}}
25 
26 struct s {
27   __externref_t f1;       // expected-error {{field has sizeless type '__externref_t'}}
28   __externref_t f2[0];    // expected-error {{field has sizeless type '__externref_t'}}
29   __externref_t f3[];     // expected-error {{field has sizeless type '__externref_t'}}
30   __externref_t f4[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
31   __externref_t *f5;      // expected-error {{pointer to WebAssembly reference type is not allowed}}
32   __externref_t ****f6;   // expected-error {{pointer to WebAssembly reference type is not allowed}}
33   __externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
34 };
35 
36 union u {
37   __externref_t f1;       // expected-error {{field has sizeless type '__externref_t'}}
38   __externref_t f2[0];    // expected-error {{field has sizeless type '__externref_t'}}
39   __externref_t f3[];     // expected-error {{field has sizeless type '__externref_t'}}
40   __externref_t f4[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
41   __externref_t *f5;      // expected-error {{pointer to WebAssembly reference type is not allowed}}
42   __externref_t ****f6;   // expected-error {{pointer to WebAssembly reference type is not allowed}}
43   __externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
44 };
45 
46 void illegal_argument_1(__externref_t table[]);     // expected-error {{cannot use WebAssembly table as a function parameter}}
47 void illegal_argument_2(__externref_t table[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
48 void illegal_argument_3(__externref_t *table);      // expected-error {{pointer to WebAssembly reference type is not allowed}}
49 void illegal_argument_4(__externref_t ***table);    // expected-error {{pointer to WebAssembly reference type is not allowed}}
50 void illegal_argument_5(__externref_t (*table)[0]); // expected-error {{cannot form a pointer to a WebAssembly table}}
51 void illegal_argument_6(__externref_t table[0]);    // expected-error {{cannot use WebAssembly table as a function parameter}}
52 
53 __externref_t *illegal_return_1();   // expected-error {{pointer to WebAssembly reference type is not allowed}}
54 __externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}}
55 __externref_t (*illegal_return_3())[0]; // expected-error {{cannot form a pointer to a WebAssembly table}}
56 
57 void varargs(int, ...);
58 typedef void (*__funcref funcref_t)();
59 typedef void (*__funcref __funcref funcref_fail_t)(); // expected-warning {{attribute '__funcref' is already applied}}
60 
func(__externref_t ref)61 __externref_t func(__externref_t ref) {
62   &ref;                        // expected-error {{cannot take address of WebAssembly reference}}
63   int foo = 40;
64   (__externref_t *)(&foo);     // expected-error {{pointer to WebAssembly reference type is not allowed}}
65   (__externref_t ****)(&foo);  // expected-error {{pointer to WebAssembly reference type is not allowed}}
66   sizeof(ref);                 // expected-error {{invalid application of 'sizeof' to sizeless type '__externref_t'}}
67   sizeof(__externref_t);       // expected-error {{invalid application of 'sizeof' to sizeless type '__externref_t'}}
68   sizeof(__externref_t[0]);    // expected-error {{invalid application of 'sizeof' to WebAssembly table}}
69   sizeof(table);               // expected-error {{invalid application of 'sizeof' to WebAssembly table}}
70   sizeof(__externref_t[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
71   sizeof(__externref_t *);     // expected-error {{pointer to WebAssembly reference type is not allowed}}
72   sizeof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
73   // expected-warning@+1 {{'_Alignof' applied to an expression is a GNU extension}}
74   _Alignof(ref);                 // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
75   _Alignof(__externref_t);       // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
76   _Alignof(__externref_t[]);     // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
77   _Alignof(__externref_t[0]);    // expected-error {{invalid application of 'alignof' to sizeless type '__externref_t'}}
78   _Alignof(table);               // expected-warning {{'_Alignof' applied to an expression is a GNU extension}} expected-error {{invalid application of 'alignof' to WebAssembly table}}
79   _Alignof(__externref_t[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
80   _Alignof(__externref_t *);     // expected-error {{pointer to WebAssembly reference type is not allowed}}
81   _Alignof(__externref_t ***);   // expected-error {{pointer to WebAssembly reference type is not allowed}};
82   varargs(1, ref);               // expected-error {{cannot pass expression of type '__externref_t' to variadic function}}
83 
84   __externref_t lt1[0];           // expected-error {{WebAssembly table cannot be declared within a function}}
85   static __externref_t lt2[0];    // expected-error {{WebAssembly table cannot be declared within a function}}
86   static __externref_t lt3[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}}
87   static __externref_t(*lt4)[0];  // expected-error {{cannot form a pointer to a WebAssembly table}}
88   // conly-error@+2 {{cannot use WebAssembly table as a function parameter}}
89   // cpp-error@+1 {{no matching function for call to 'illegal_argument_1'}}
90   illegal_argument_1(table);
91   varargs(1, table);              // expected-error {{cannot use WebAssembly table as a function parameter}}
92   table == 1;                     // expected-error {{invalid operands to binary expression ('__attribute__((address_space(1))) __externref_t[0]' and 'int')}}
93   1 >= table;                     // expected-error {{invalid operands to binary expression ('int' and '__attribute__((address_space(1))) __externref_t[0]')}}
94   table == other_table;           // expected-error {{invalid operands to binary expression ('__attribute__((address_space(1))) __externref_t[0]' and '__attribute__((address_space(1))) __externref_t[0]')}}
95   table !=- table;                // expected-error {{invalid argument type '__attribute__((address_space(1))) __externref_t *' to unary expression}}
96   !table;                         // expected-error {{invalid argument type '__attribute__((address_space(1))) __externref_t *' to unary expression}}
97   1 && table;                     // expected-error {{invalid operands to binary expression ('int' and '__attribute__((address_space(1))) __externref_t[0]')}}
98   table || 1;                     // expected-error {{invalid operands to binary expression ('__attribute__((address_space(1))) __externref_t[0]' and 'int')}}
99   1 ? table : table;              // expected-error {{cannot use a WebAssembly table within a branch of a conditional expression}}
100   table ? : other_table;          // expected-error {{cannot use a WebAssembly table within a branch of a conditional expression}}
101   (void *)table;                  // expected-error {{cannot cast from a WebAssembly table}}
102   void *u;
103   u = table;                      // expected-error {{cannot assign a WebAssembly table}}
104   void *v = table;                // expected-error {{cannot assign a WebAssembly table}}
105   &table;                         // expected-error {{cannot form a reference to a WebAssembly table}}
106   (void)table;
107 
108   table[0];                       // expected-error {{cannot subscript a WebAssembly table}}
109   table[0] = ref;                 // expected-error {{cannot subscript a WebAssembly table}}
110 
111   int i = 0;                      // cpp-note {{declared here}}
112   __externref_t oh_no_vlas[i];    // expected-error {{WebAssembly table cannot be declared within a function}} \
113                                      cpp-warning {{variable length arrays in C++ are a Clang extension}} \
114                                      cpp-note {{read of non-const variable 'i' is not allowed in a constant expression}}
115 
116   return ref;
117 }
118 
foo()119 void foo() {
120   static __externref_t t[0];      // expected-error {{WebAssembly table cannot be declared within a function}}
121   {
122     static __externref_t t2[0];   // expected-error {{WebAssembly table cannot be declared within a function}}
123     for (;;) {
124       static __externref_t t3[0]; // expected-error {{WebAssembly table cannot be declared within a function}}
125     }
126   }
127   int i = ({
128     static __externref_t t4[0];   // expected-error {{WebAssembly table cannot be declared within a function}}
129     1;
130   });
131 }
132 
ret_void_ptr()133 void *ret_void_ptr() {
134   return table; // expected-error {{cannot return a WebAssembly table}}
135 }
136