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 &out, int *inst) {
+ static void* dispatch_table[] = {&&inc, // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &&suspend, // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ &&stop}; // 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 &out, int *inst) {
+ void* dispatch_table[] = {nullptr, nullptr, nullptr};
+ dispatch_table[0] = &&inc; // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ dispatch_table[1] = &&suspend; // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ dispatch_table[2] = &&stop; // 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 &out, int *inst) {
+ void* dispatch_table[] = {nullptr, nullptr, nullptr};
+ [&]() -> resumable {
+ dispatch_table[0] = &&inc; // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ dispatch_table[1] = &&suspend; // expected-error {{the GNU address of label extension is not allowed in coroutines.}}
+ dispatch_table[2] = &&stop; // 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
===================================================================
--- clang/include/clang/Sema/ScopeInfo.h
+++ clang/include/clang/Sema/ScopeInfo.h
@@ -233,6 +233,9 @@
/// modified in the function.
llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
+ /// The set of GNU address of label extension "&&label".
+ llvm::SmallVector<AddrLabelExpr *, 4> AddrLabels;
+
public:
/// Represents a simple identification of a weak object.
///
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11260,6 +11260,9 @@
def err_coroutine_unusable_new : Error<
"'operator new' provided by %0 is not usable with the function signature of %1"
>;
+def err_coro_invalid_addr_of_label : Error<
+ "the GNU address of label extension is not allowed in coroutines."
+>;
} // end of coroutines issue category
let CategoryName = "Documentation Issue" in {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits