1# RUN: not llvm-mc -triple=wasm32 -mattr=+exception-handling,+reference-types,+tail-call %s 2>&1 | FileCheck %s
2
3# These tests are intended to act as a litmus test for the WebAssembly ASM
4# type-checker - both in terms of errors it can catch and in terms of the
5# location information used in the error messages.
6
7local_get_no_local_type:
8  .functype local_get_no_local_type () -> ()
9# CHECK: :[[@LINE+1]]:13: error: no local type specified for index 0
10  local.get 0
11  end_function
12
13local_set_no_local_type:
14  .functype local_set_no_local_type () -> ()
15# CHECK: :[[@LINE+1]]:13: error: no local type specified for index 0
16  local.set 0
17  end_function
18
19local_set_empty_stack_while_popping:
20  .functype local_set_empty_stack_while_popping () -> ()
21  .local i32
22# CHECK: [[@LINE+1]]:3: error: empty stack while popping i32
23  local.set 0
24  end_function
25
26local_set_type_mismatch:
27  .functype local_set_type_mismatch () -> ()
28  .local i32
29  f32.const 1.0
30# CHECK: [[@LINE+1]]:3: error: popped f32, expected i32
31  local.set 0
32  end_function
33
34local_tee_no_local_type:
35  .functype local_tee_no_local_type () -> ()
36# CHECK: :[[@LINE+1]]:13: error: no local type specified for index 0
37  local.tee 0
38  end_function
39
40local_tee_empty_stack_while_popping:
41  .functype local_tee_empty_stack_while_popping () -> ()
42  .local f32
43# CHECK: :[[@LINE+1]]:3: error: empty stack while popping f32
44  local.tee 0
45  end_function
46
47local_tee_type_mismatch:
48  .functype local_tee_type_mismatch () -> ()
49  .local f32
50  i32.const 1
51# CHECK: :[[@LINE+1]]:3: error: popped i32, expected f32
52  local.tee 0
53  end_function
54
55global_get_missing_globaltype:
56  .functype global_get_missing_globaltype () -> ()
57# CHECK: :[[@LINE+1]]:14: error: symbol foo missing .globaltype
58  global.get foo
59  end_function
60
61global_get_expected_expression_operand:
62  .functype global_get_expected_expression_operand () -> ()
63# CHECK: :[[@LINE+1]]:14: error: expected expression operand
64  global.get 1
65  end_function
66
67global_set_missing_globaltype:
68  .functype global_set_missing_globaltype () -> ()
69# CHECK: :[[@LINE+1]]:14: error: symbol foo missing .globaltype
70  global.set foo
71  end_function
72
73global_set_expected_expression_operand:
74  .functype global_set_expected_expression_operand () -> ()
75# CHECK: :[[@LINE+1]]:14: error: expected expression operand
76  global.set 1
77  end_function
78
79global_set_empty_stack_while_popping:
80  .functype global_set_empty_stack_while_popping () -> ()
81  .globaltype valid_global, i64
82# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i64
83  global.set valid_global
84  end_function
85
86global_set_type_mismatch:
87  .functype global_set_type_mismatch () -> ()
88  .globaltype valid_global, i64
89  i32.const 1
90# CHECK: :[[@LINE+1]]:3: error: popped i32, expected i64
91  global.set valid_global
92  end_function
93
94table_get_expected_expression_operand:
95  .functype table_get_expected_expression_operand () -> ()
96# CHECK: :[[@LINE+1]]:13: error: expected expression operand
97  table.get 1
98  end_function
99
100table_get_missing_tabletype:
101  .functype table_get_missing_tabletype () -> ()
102# CHECK: :[[@LINE+1]]:13: error: symbol foo missing .tabletype
103  table.get foo
104  end_function
105
106.tabletype valid_table, externref
107
108table_get_empty_stack_while_popping:
109  .functype table_get_empty_stack_while_popping () -> ()
110# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
111  table.get valid_table
112  end_function
113
114table_get_type_mismatch:
115  .functype table_get_type_mismatch () -> ()
116  f32.const 1.0
117# CHECK: :[[@LINE+1]]:3: error: popped f32, expected i32
118  table.get valid_table
119  end_function
120
121table_set_expected_expression_operand:
122  .functype table_set_expected_expression_operand () -> ()
123# CHECK: :[[@LINE+1]]:13: error: expected expression operand
124  table.set 1
125  end_function
126
127table_set_missing_tabletype:
128  .functype table_set_missing_tabletype () -> ()
129# CHECK: :[[@LINE+1]]:13: error: symbol foo missing .tabletype
130  table.set foo
131  end_function
132
133table_set_empty_stack_while_popping_1:
134  .functype table_set_empty_stack_while_popping_1 () -> ()
135# CHECK: :[[@LINE+1]]:3: error: empty stack while popping externref
136  table.set valid_table
137  end_function
138
139table_set_empty_stack_while_popping_2:
140  .functype table_set_empty_stack_while_popping_2 (externref) -> ()
141  local.get 0
142# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
143  table.set valid_table
144  end_function
145
146table_set_type_mismatch_1:
147  .functype table_set_type_mismatch_1 () -> ()
148  ref.null_func
149# CHECK: :[[@LINE+1]]:3: error: popped funcref, expected externref
150  table.set valid_table
151  end_function
152
153table_set_type_mismatch_2:
154  .functype table_set_type_mismatch_2 () -> ()
155  f32.const 1.0
156  ref.null_extern
157# CHECK: :[[@LINE+1]]:3: error: popped f32, expected i32
158  table.set valid_table
159  end_function
160
161table_fill_expected_expression_operand:
162  .functype table_fill_expected_expression_operand () -> ()
163# CHECK: :[[@LINE+1]]:14: error: expected expression operand
164  table.fill 1
165  end_function
166
167table_fill_missing_tabletype:
168  .functype table_fill_missing_tabletype () -> ()
169# CHECK: :[[@LINE+1]]:14: error: symbol foo missing .tabletype
170  table.fill foo
171  end_function
172
173table_fill_empty_stack_while_popping_1:
174  .functype table_fill_empty_stack_while_popping_1 () -> ()
175# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
176  table.fill valid_table
177  end_function
178
179table_fill_empty_stack_while_popping_2:
180  .functype table_fill_empty_stack_while_popping_2 (i32) -> ()
181  local.get 0
182# CHECK: :[[@LINE+1]]:3: error: empty stack while popping externref
183  table.fill valid_table
184  end_function
185
186table_fill_empty_stack_while_popping_3:
187  .functype table_fill_empty_stack_while_popping_3 (i32, externref) -> ()
188  local.get 1
189  local.get 0
190# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
191  table.fill valid_table
192  end_function
193
194table_fill_type_mismatch_1:
195  .functype table_fill_type_mismatch_1 () -> ()
196  ref.null_func
197# CHECK: :[[@LINE+1]]:3: error: popped funcref, expected i32
198  table.fill valid_table
199  end_function
200
201table_fill_type_mismatch_2:
202  .functype table_fill_type_mismatch_2 () -> ()
203  ref.null_func
204  i32.const 1
205# CHECK: [[@LINE+1]]:3: error: popped funcref, expected externref
206  table.fill valid_table
207  end_function
208
209table_fill_type_mismatch_3:
210  .functype table_fill_type_mismatch_3 () -> ()
211  f32.const 2.0
212  ref.null_extern
213  i32.const 1
214# CHECK: :[[@LINE+1]]:3: error: popped f32, expected i32
215  table.fill valid_table
216  end_function
217
218drop_empty_stack_while_popping:
219  .functype drop_empty_stack_while_popping () -> ()
220# CHECK: :[[@LINE+1]]:3: error: empty stack while popping value
221  drop
222  end_function
223
224end_block_insufficient_values_on_stack:
225  .functype end_block_insufficient_values_on_stack () -> ()
226  block i32
227# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack
228  end_block
229  end_function
230
231end_block_type_mismatch:
232  .functype end_block_type_mismatch () -> ()
233  block i32
234  f32.const 1.0
235# CHECK: :[[@LINE+1]]:3: error: end got f32, expected i32
236  end_block
237  end_function
238
239end_loop_insufficient_values_on_stack:
240  .functype end_loop_insufficient_values_on_stack () -> ()
241  loop i32
242# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack
243  end_loop
244  end_function
245
246end_loop_type_mismatch:
247  .functype end_loop_type_mismatch () -> ()
248  loop f32
249  i32.const 1
250# CHECK: :[[@LINE+1]]:3: error: end got i32, expected f32
251  end_loop
252  end_function
253
254end_if_insufficient_values_on_stack:
255  .functype end_if_insufficient_values_on_stack () -> ()
256  i32.const 1
257  if i32
258# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack
259  end_if
260  end_function
261
262end_if_type_mismatch:
263  .functype end_if_type_mismatch () -> ()
264  i32.const 1
265  if f32
266  i32.const 1
267# CHECK: :[[@LINE+1]]:3: error: end got i32, expected f32
268  end_if
269  end_function
270
271else_insufficient_values_on_stack:
272  .functype else_insufficient_values_on_stack () -> ()
273  i32.const 1
274  if i32
275  i32.const 2
276  else
277# FIXME: Should complain about insufficient values on the stack.
278  end_if
279# FIXME: Should complain about superflous value on the stack.
280  end_function
281
282else_type_mismatch:
283  .functype else_type_mismatch () -> ()
284  i32.const 1
285  if i32
286  i32.const 2
287  else
288# FIXME: Should complain about a type mismatch.
289  f32.const 3.0
290  end_if
291  drop
292  end_function
293
294end_try_insufficient_values_on_stack:
295  .functype end_try_insufficient_values_on_stack () -> ()
296  try i32
297# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack
298  end_try
299  end_function
300
301end_try_type_mismatch:
302  .functype end_try_type_mismatch () -> ()
303  try i32
304  f32.const 1.0
305# CHECK: :[[@LINE+1]]:3: error: end got f32, expected i32
306  end_try
307  end_function
308
309end_function_empty_stack_while_popping:
310  .functype end_function_empty_stack_while_popping () -> (i32)
311# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
312  end_function
313
314end_function_type_mismatch:
315  .functype end_function_type_mismatch () -> (f32)
316  i32.const 1
317# CHECK: :[[@LINE+1]]:3: error: popped i32, expected f32
318  end_function
319
320end_function_superfluous_end_function_values:
321  .functype end_function_superfluous_end_function_values () -> ()
322  i32.const 1
323  f32.const 2.0
324# CHECK: :[[@LINE+1]]:3: error: 2 superfluous return values
325  end_function
326
327return_empty_stack_while_popping:
328  .functype return_empty_stack_while_popping () -> (i32)
329# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
330  return
331  end_function
332
333return_type_mismatch:
334  .functype return_type_mismatch () -> (f32)
335  i32.const 1
336# CHECK: :[[@LINE+1]]:3: error: popped i32, expected f32
337  return
338  end_function
339
340# Missing index for call_indirect.
341call_indirect_empty_stack_while_popping_1:
342  .functype call_indirect_empty_stack_while_popping_1 () -> ()
343# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
344  call_indirect () -> ()
345  end_function
346
347# Missing arguments for target of call_indirect.
348call_indirect_empty_stack_while_popping_2:
349  .functype call_indirect_empty_stack_while_popping_1 (f32) -> ()
350  i32.const 1
351# CHECK: :[[@LINE+1]]:3: error: empty stack while popping f32
352  call_indirect (f32) -> ()
353  end_function
354
355call_indirect_type_mismatch_for_argument:
356  .functype call_indirect_type_mismatch_for_argument () -> ()
357  i32.const 1
358  i32.const 2
359# CHECK: :[[@LINE+1]]:3: error: popped i32, expected f32
360  call_indirect (f32) -> ()
361  end_function
362
363call_indirect_superfluous_value_at_end:
364  .functype call_indirect_superfluous_value_at_end () -> ()
365  i32.const 1
366  call_indirect () -> (i64)
367# CHECK: :[[@LINE+1]]:3: error: 1 superfluous return values
368  end_function
369
370# Missing index for return_call_indirect.
371return_call_indirect_empty_stack_while_popping_1:
372  .functype return_call_indirect_empty_stack_while_popping_1 () -> ()
373# CHECK: :[[@LINE+1]]:3: error: empty stack while popping i32
374  return_call_indirect () -> ()
375  end_function
376
377# Missing arguments for target of return_call_indirect.
378return_call_indirect_empty_stack_while_popping_2:
379  .functype return_call_indirect_empty_stack_while_popping_2 () -> ()
380  i32.const 1
381# CHECK: :[[@LINE+1]]:3: error: empty stack while popping f32
382  return_call_indirect (f32) -> ()
383  end_function
384
385call_expected_expression_operand:
386  .functype call_expected_expression_operand () -> ()
387# CHECK: :[[@LINE+1]]:8: error: expected expression operand
388  call 1
389  end_function
390
391.functype fn_i32_to_void (i32) -> ()
392
393call_empty_stack_while_popping:
394  .functype call_empty_stack_while_popping () -> ()
395# CHECK: [[@LINE+1]]:3: error: empty stack while popping i32
396  call fn_i32_to_void
397  end_function
398
399call_type_mismatch:
400  .functype call_type_mismatch () -> ()
401  f32.const 1.0
402# CHECK: :[[@LINE+1]]:3: error: popped f32, expected i32
403  call fn_i32_to_void
404  end_function
405
406.functype fn_void_to_i32 () -> (i32)
407
408call_superfluous_value_at_end:
409  .functype call_superfluous_value_at_end () -> ()
410  call fn_void_to_i32
411# CHECK: :[[@LINE+1]]:3: error: 1 superfluous return values
412  end_function
413
414call_missing_functype:
415  .functype call_missing_functype () -> ()
416# CHECK: :[[@LINE+1]]:8: error: symbol no_functype missing .functype
417  call no_functype
418  end_function
419
420return_call_expected_expression_operand:
421  .functype return_call_expected_expression_operand () -> ()
422# CHECK: :[[@LINE+1]]:15: error: expected expression operand
423  return_call 1
424  end_function
425
426return_call_empty_stack_while_popping:
427  .functype return_call_empty_stack_while_popping () -> ()
428# CHECK: [[@LINE+1]]:3: error: empty stack while popping i32
429  return_call fn_i32_to_void
430  end_function
431
432return_call_type_mismatch:
433  .functype return_call_type_mismatch () -> ()
434  f32.const 1.0
435# CHECK: :[[@LINE+1]]:3: error: popped f32, expected i32
436  return_call fn_i32_to_void
437  end_function
438
439return_call_missing_functype:
440  .functype return_call_missing_functype () -> ()
441# CHECK: :[[@LINE+1]]:15: error: symbol no_functype missing .functype
442  return_call no_functype
443  end_function
444
445catch_expected_expression_operand:
446  .functype catch_expected_expression_operand () -> ()
447  try
448# CHECK: :[[@LINE+1]]:9: error: expected expression operand
449  catch 1
450  end_try
451  end_function
452
453catch_missing_tagtype:
454  .functype catch_missing_tagtype () -> ()
455  try
456# CHECK: :[[@LINE+1]]:9: error: symbol no_tagtype missing .tagtype
457  catch no_tagtype
458  end_try
459  end_function
460
461catch_superfluous_value_at_end:
462  .functype catch_superfluous_value_at_end () -> ()
463  .tagtype tag_i32 i32
464  try
465  catch tag_i32
466  end_try
467# FIXME: Superfluous value should be caught at end_try?
468# CHECK: :[[@LINE+1]]:3: error: 1 superfluous return values
469  end_function
470
471ref_is_null_empty_stack_while_popping:
472  .functype ref_is_null_empty_stack_while_popping () -> ()
473# CHECK: [[@LINE+1]]:3: error: empty stack while popping reftype
474  ref.is_null
475  end_function
476
477ref_is_null_type_mismatch:
478  .functype ref_is_null_type_mismatch () -> ()
479  i32.const 1
480# CHECK: [[@LINE+1]]:3: error: popped i32, expected reftype
481  ref.is_null
482  end_function
483
484ref_is_null_pushes_i32:
485  .functype ref_is_null_pushes_i32 () -> (i64)
486  ref.null_func
487  ref.is_null
488# CHECK: :[[@LINE+1]]:3: error: popped i32, expected i64
489  end_function
490
491# For the other instructions, the type checker checks vs the operands in the
492# instruction definition. Perform some simple checks for these rather than
493# exhaustively testing all instructions.
494
495other_insn_test_1:
496  .functype other_insn_test_1 () -> ()
497# CHECK: [[@LINE+1]]:3: error: empty stack while popping i32
498  i32.add
499  end_function
500
501other_insn_test_2:
502  .functype other_insn_test_2 () -> ()
503  i32.const 1
504  ref.null_func
505# CHECK: :[[@LINE+1]]:3: error: popped funcref, expected i32
506  i32.add
507  end_function
508
509other_insn_test_3:
510  .functype other_insn_test_3 () -> ()
511  f32.const 1.0
512  f32.const 2.0
513  f32.add
514# CHECK: :[[@LINE+1]]:3: error: 1 superfluous return values
515  end_function
516