xref: /llvm-project/clang/test/SemaCXX/addr-label-in-coroutines.cpp (revision b49ce9c304b00dae49148b6a2f5f27965000206c)
1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
2 
3 #include "Inputs/std-coroutine.h"
4 
5 struct resumable {
6   struct promise_type {
get_return_objectresumable::promise_type7     resumable get_return_object() { return {}; }
initial_suspendresumable::promise_type8     auto initial_suspend() { return std::suspend_always(); }
final_suspendresumable::promise_type9     auto final_suspend() noexcept { return std::suspend_always(); }
unhandled_exceptionresumable::promise_type10     void unhandled_exception() {}
return_voidresumable::promise_type11     void return_void(){};
12   };
13 };
14 
f1(int & out,int * inst)15 resumable f1(int &out, int *inst) {
16     static void* dispatch_table[] = {&&inc,      // expected-error {{the GNU address of label extension is not allowed in coroutines}}
17                                      &&suspend,  // expected-error {{the GNU address of label extension is not allowed in coroutines}}
18                                      &&stop};    // expected-error {{the GNU address of label extension is not allowed in coroutines}}
19     #define DISPATCH() goto *dispatch_table[*inst++]
20 inc:
21     out++;
22     DISPATCH();
23 
24 suspend:
25     co_await std::suspend_always{};
26     DISPATCH();
27 
28 stop:
29     co_return;
30 }
31 
f2(int & out,int * inst)32 resumable f2(int &out, int *inst) {
33     void* dispatch_table[] = {nullptr, nullptr, nullptr};
34     dispatch_table[0] = &&inc;      // expected-error {{the GNU address of label extension is not allowed in coroutines}}
35     dispatch_table[1] = &&suspend;  // expected-error {{the GNU address of label extension is not allowed in coroutines}}
36     dispatch_table[2] = &&stop;     // expected-error {{the GNU address of label extension is not allowed in coroutines}}
37     #define DISPATCH() goto *dispatch_table[*inst++]
38 inc:
39     out++;
40     DISPATCH();
41 
42 suspend:
43     co_await std::suspend_always{};
44     DISPATCH();
45 
46 stop:
47     co_return;
48 }
49 
f3(int & out,int * inst)50 resumable f3(int &out, int *inst) {
51     void* dispatch_table[] = {nullptr, nullptr, nullptr};
52     [&]() -> resumable {
53         dispatch_table[0] = &&inc;      // expected-error {{the GNU address of label extension is not allowed in coroutines}}
54         dispatch_table[1] = &&suspend;  // expected-error {{the GNU address of label extension is not allowed in coroutines}}
55         dispatch_table[2] = &&stop;     // expected-error {{the GNU address of label extension is not allowed in coroutines}}
56         #define DISPATCH() goto *dispatch_table[*inst++]
57     inc:
58         out++;
59         DISPATCH();
60 
61     suspend:
62         co_await std::suspend_always{};
63         DISPATCH();
64 
65     stop:
66         co_return;
67     }();
68 
69     co_return;
70 }
71