[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2023-01-16 Thread Chuanqi Xu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGcc526e346deb: [C++20] [Coroutines] Disable to take the 
address of labels in coroutines (authored by ChuanqiXu).

Changed prior to commit:
  https://reviews.llvm.org/D131938?vs=452925=489677#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/addr-label-in-coroutines.cpp

Index: clang/test/SemaCXX/addr-label-in-coroutines.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/addr-label-in-coroutines.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+#include "Inputs/std-coroutine.h"
+
+struct resumable {
+  struct promise_type {
+resumable get_return_object() { return {}; }
+auto initial_suspend() { return std::suspend_always(); }
+auto final_suspend() noexcept { return std::suspend_always(); }
+void unhandled_exception() {}
+void return_void(){};
+  };
+};
+
+resumable f1(int , int *inst) {
+static void* dispatch_table[] = {&,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &};// expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f2(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f3(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+[&]() -> resumable {
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}();
+
+co_return;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16105,8 +16105,13 @@
 LabelDecl *TheDecl) {
   TheDecl->markUsed(Context);
   // Create the AST node.  The address of a label always has type 'void*'.
-  return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
- Context.getPointerType(Context.VoidTy));
+  auto *Res = new (Context) AddrLabelExpr(
+  OpLoc, LabLoc, TheDecl, Context.getPointerType(Context.VoidTy));
+
+  if (getCurFunction())
+getCurFunction()->AddrLabels.push_back(Res);
+
+  return Res;
 }
 
 void Sema::ActOnStartStmtExpr() {
Index: clang/lib/Sema/SemaCoroutine.cpp
===
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -1125,6 +1125,12 @@
 Diag(Fn->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
 << Fn->getFirstCoroutineStmtKeyword();
   }
+
+  // Coroutines will get splitted into pieces. The GNU address of label
+  // extension wouldn't be meaningful in coroutines.
+  for (AddrLabelExpr *ALE : Fn->AddrLabels)
+Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
+
   CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
   if (Builder.isInvalid() || !Builder.buildStatements())
 return FD->setInvalidDecl();
Index: clang/lib/Sema/ScopeInfo.cpp
===
--- clang/lib/Sema/ScopeInfo.cpp
+++ clang/lib/Sema/ScopeInfo.cpp
@@ -56,6 +56,7 @@
   ModifiedNonNullParams.clear();
   Blocks.clear();
   

[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2023-01-16 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu accepted this revision.
ChuanqiXu added a comment.
This revision is now accepted and ready to land.

Oh, sorry, I forgot this. Given D132084  is 
not updated recently, I think we can merge this first. And it should be fine to 
remove this one after patches like D132084  
works properly.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-11-14 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang added a comment.

Personally, I am fine with this change as in review right now.

@ychen are you still planning to look further into this issue as part of your 
alternative patch https://reviews.llvm.org/D132084 ? Otherwise, I would propose 
that we merge @ChuanqiXu 's change for the time being. Later on, we can still 
re-enable this functionality, as soon as we figured out the LLVM coroutine 
semantics of this


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-08-16 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu added a comment.

In D131938#3727954 , @ychen wrote:

>> Since the coroutines are going to split into pieces in the middle end so the 
>> address of labels are ambiguous that time.
>
> Do we split in the middle or copy the whole computed goto CFG?

Yes.

> I'd imagine the branch on a dynamic block address is like `n`-way branch 
> which is not feasible to split. Does/Would it fix the problem by letting the 
> ramp/resume function each have its own dispatch table? I skimmed through the 
> blockaddress handling during function cloning which looks insufficient to 
> handle this issue: 
> https://github.com/llvm/llvm-project/blob/e20d210eef92f3952de0e89ef2f01a146480a13b/llvm/lib/Transforms/Utils/CloneFunction.cpp#L177-L182,
>  it says "It is only legal to clone a function if a block address within that 
> function is never referenced outside of the function." . This is not true 
> when the dispatch table is a global variable.

The key problem here is that the compiler don't know the idea 'dispatch table'. 
The dispatch table is just a global variable. And coroutines should just leave 
the global variable there just like other global variables.

> "It is only legal to clone a function if a block address within that function 
> is never referenced outside of the function."

This also shows the problem. The coroutines are multiple functions indeed.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-08-16 Thread Yuanfang Chen via Phabricator via cfe-commits
ychen added a comment.

> Since the coroutines are going to split into pieces in the middle end so the 
> address of labels are ambiguous that time.

Do we split in the middle or copy the whole computed goto CFG? I'd imagine the 
branch on a dynamic block address is like `n`-way branch which is not feasible 
to split. Does it fix the problem by letting the ramp/result each have their 
own dispatch table? I skimmed through the blockaddress handling during function 
cloning which looks insufficient to handle this issue: 
https://github.com/llvm/llvm-project/blob/e20d210eef92f3952de0e89ef2f01a146480a13b/llvm/lib/Transforms/Utils/CloneFunction.cpp#L177-L182,
 it says "It is only legal to clone a function if a block address within that 
function is never referenced outside of the function." . This is not true when 
the dispatch table is a global variable.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-08-16 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu updated this revision to Diff 452925.
ChuanqiXu added a comment.

Address comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/addr-label-in-coroutines.cpp

Index: clang/test/SemaCXX/addr-label-in-coroutines.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/addr-label-in-coroutines.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+#include "Inputs/std-coroutine.h"
+
+struct resumable {
+  struct promise_type {
+resumable get_return_object() { return {}; }
+auto initial_suspend() { return std::suspend_always(); }
+auto final_suspend() noexcept { return std::suspend_always(); }
+void unhandled_exception() {}
+void return_void(){};
+  };
+};
+
+resumable f1(int , int *inst) {
+static void* dispatch_table[] = {&,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &};// expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f2(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f3(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+[&]() -> resumable {
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}();
+
+co_return;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15840,8 +15840,13 @@
 LabelDecl *TheDecl) {
   TheDecl->markUsed(Context);
   // Create the AST node.  The address of a label always has type 'void*'.
-  return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
- Context.getPointerType(Context.VoidTy));
+  auto *Res = new (Context) AddrLabelExpr(
+  OpLoc, LabLoc, TheDecl, Context.getPointerType(Context.VoidTy));
+
+  if (getCurFunction())
+getCurFunction()->AddrLabels.push_back(Res);
+
+  return Res;
 }
 
 void Sema::ActOnStartStmtExpr() {
Index: clang/lib/Sema/SemaCoroutine.cpp
===
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -1103,6 +1103,12 @@
 Diag(Fn->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
 << Fn->getFirstCoroutineStmtKeyword();
   }
+
+  // Coroutines will get splitted into pieces. The GNU address of label
+  // extension wouldn't be meaningful in coroutines.
+  for (AddrLabelExpr *ALE : Fn->AddrLabels)
+Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
+
   CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
   if (Builder.isInvalid() || !Builder.buildStatements())
 return FD->setInvalidDecl();
Index: clang/lib/Sema/ScopeInfo.cpp
===
--- clang/lib/Sema/ScopeInfo.cpp
+++ clang/lib/Sema/ScopeInfo.cpp
@@ -56,6 +56,7 @@
   ModifiedNonNullParams.clear();
   Blocks.clear();
   ByrefBlockVars.clear();
+  AddrLabels.clear();
 }
 
 static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
Index: clang/include/clang/Sema/ScopeInfo.h

[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-08-16 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang added a comment.

looks good to me on a high-level, but I don't know clang well enough to 
confidently approve this change




Comment at: clang/lib/Sema/SemaCoroutine.cpp:1107
+
+  // Corotuines will get splitted into pieces. The GNU address of label
+  // extension wouldn't be meaningful in coroutines.

Corotuines -> Coroutines



Comment at: clang/test/SemaCXX/addr-label-in-coroutines.cpp:5
+
+struct Allocator {};
+

unused


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-08-15 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu updated this revision to Diff 452880.
ChuanqiXu added a comment.

Add ReleaseNotes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131938/new/

https://reviews.llvm.org/D131938

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/addr-label-in-coroutines.cpp

Index: clang/test/SemaCXX/addr-label-in-coroutines.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/addr-label-in-coroutines.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+#include "Inputs/std-coroutine.h"
+
+struct Allocator {};
+
+struct resumable {
+  struct promise_type {
+resumable get_return_object() { return {}; }
+auto initial_suspend() { return std::suspend_always(); }
+auto final_suspend() noexcept { return std::suspend_always(); }
+void unhandled_exception() {}
+void return_void(){};
+  };
+};
+
+resumable f1(int , int *inst) {
+static void* dispatch_table[] = {&,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &};// expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f2(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f3(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+[&]() -> resumable {
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}();
+
+co_return;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15840,8 +15840,13 @@
 LabelDecl *TheDecl) {
   TheDecl->markUsed(Context);
   // Create the AST node.  The address of a label always has type 'void*'.
-  return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
- Context.getPointerType(Context.VoidTy));
+  auto *Res = new (Context) AddrLabelExpr(
+  OpLoc, LabLoc, TheDecl, Context.getPointerType(Context.VoidTy));
+
+  if (getCurFunction())
+getCurFunction()->AddrLabels.push_back(Res);
+
+  return Res;
 }
 
 void Sema::ActOnStartStmtExpr() {
Index: clang/lib/Sema/SemaCoroutine.cpp
===
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -1103,6 +1103,12 @@
 Diag(Fn->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
 << Fn->getFirstCoroutineStmtKeyword();
   }
+
+  // Corotuines will get splitted into pieces. The GNU address of label
+  // extension wouldn't be meaningful in coroutines.
+  for (AddrLabelExpr *ALE : Fn->AddrLabels)
+Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
+
   CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
   if (Builder.isInvalid() || !Builder.buildStatements())
 return FD->setInvalidDecl();
Index: clang/lib/Sema/ScopeInfo.cpp
===
--- clang/lib/Sema/ScopeInfo.cpp
+++ clang/lib/Sema/ScopeInfo.cpp
@@ -56,6 +56,7 @@
   ModifiedNonNullParams.clear();
   Blocks.clear();
   ByrefBlockVars.clear();
+  AddrLabels.clear();
 }
 
 static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
Index: clang/include/clang/Sema/ScopeInfo.h

[PATCH] D131938: [C++20] [Coroutines] Disable to take the address of labels in coroutines

2022-08-15 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu created this revision.
ChuanqiXu added reviewers: aaron.ballman, erichkeane, ychen, avogelsgesang.
ChuanqiXu added a project: clang.
Herald added a project: All.
ChuanqiXu requested review of this revision.
Herald added a subscriber: cfe-commits.

Closing https://github.com/llvm/llvm-project/issues/56436

We can't support the GNU address of label extension in coroutines well in 
current architecture. To avoid any further misunderstanding, we try to emit an 
error here.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131938

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/addr-label-in-coroutines.cpp

Index: clang/test/SemaCXX/addr-label-in-coroutines.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/addr-label-in-coroutines.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+#include "Inputs/std-coroutine.h"
+
+struct Allocator {};
+
+struct resumable {
+  struct promise_type {
+resumable get_return_object() { return {}; }
+auto initial_suspend() { return std::suspend_always(); }
+auto final_suspend() noexcept { return std::suspend_always(); }
+void unhandled_exception() {}
+void return_void(){};
+  };
+};
+
+resumable f1(int , int *inst) {
+static void* dispatch_table[] = {&,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &,  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &};// expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f2(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}
+
+resumable f3(int , int *inst) {
+void* dispatch_table[] = {nullptr, nullptr, nullptr};
+[&]() -> resumable {
+dispatch_table[0] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[1] = &  // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+dispatch_table[2] = & // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+#define DISPATCH() goto *dispatch_table[*inst++]
+inc:
+out++;
+DISPATCH();
+
+suspend:
+co_await std::suspend_always{};
+DISPATCH();
+
+stop:
+co_return;
+}();
+
+co_return;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15840,8 +15840,13 @@
 LabelDecl *TheDecl) {
   TheDecl->markUsed(Context);
   // Create the AST node.  The address of a label always has type 'void*'.
-  return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
- Context.getPointerType(Context.VoidTy));
+  auto *Res = new (Context) AddrLabelExpr(
+  OpLoc, LabLoc, TheDecl, Context.getPointerType(Context.VoidTy));
+
+  if (getCurFunction())
+getCurFunction()->AddrLabels.push_back(Res);
+
+  return Res;
 }
 
 void Sema::ActOnStartStmtExpr() {
Index: clang/lib/Sema/SemaCoroutine.cpp
===
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -1103,6 +1103,12 @@
 Diag(Fn->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
 << Fn->getFirstCoroutineStmtKeyword();
   }
+
+  // Corotuines will get splitted into pieces. The GNU address of label
+  // extension wouldn't be meaningful in coroutines.
+  for (AddrLabelExpr *ALE : Fn->AddrLabels)
+Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
+
   CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
   if (Builder.isInvalid() || !Builder.buildStatements())
 return FD->setInvalidDecl();
Index: clang/lib/Sema/ScopeInfo.cpp
===
---