[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: My understanding of deferred diagnostics is that the primary use is to allow including headers that contain inline functions, and don't properly mark device vs. host. So when you parse the function, it's unknown whether the function is actually going to be used, which would require triggering the error. (And you want this to work recursively; if you have an inline function that uses another inline function, you want to delay them both.) If we're deferring in cases where we don't need to defer, sure, let's stop doing that. But you still have an issue for diagnostics that actually do need to be delayed, I think. You need to be very careful about putting multiple tests in the same test file here: once you trigger an error anywhere, the entire module is marked as having an unrecoverable error, so the tests can conflict. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk updated
https://github.com/llvm/llvm-project/pull/147163
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH 1/6] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 0..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clan
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk updated
https://github.com/llvm/llvm-project/pull/147163
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH 1/6] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 0..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clan
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: There's one other possibility... you could make "deferred" diagnostics not defer diagnosing quite so much. If the function is defined in a way that it inherently must be emitted, or it's already been odr-used, there's no point to actually deferring the diagnostic: we know we'll emit it eventually. Otherwise, we wait until we see an ODR-use of the function: if we see such a use, we immediately diagnose that use. But I'm not quite sure how you deal with a function that's declared early, then defined inline later in the file; you'd need to recursively scan all the callers of the function. Sticking a map in the ASTContext is probably okay. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: I don't think we want to use the "isInvalidDecl" bit here. The declaration is still valid in the sense that code referring to the declaration should treat it normally. (For example, we want overload resolution to work the same way it usually does.) One way to think of this is that we're essentially inferring __device__ markings for functions that can't be built on the host. Then if it turns out we actually need the function on the host, we error out because you're trying to use a function that isn't available. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk updated
https://github.com/llvm/llvm-project/pull/147163
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH 1/5] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 0..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clan
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
@@ -2092,18 +2092,36 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
}
Sema::SemaDiagnosticBuilder
-Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
+Sema::targetDiag(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD) {
FD = FD ? FD : getCurFunctionDecl();
- if (LangOpts.OpenMP)
-return LangOpts.OpenMPIsTargetDevice
- ? OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD)
- : OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
- if (getLangOpts().CUDA)
-return getLangOpts().CUDAIsDevice ? CUDA().DiagIfDeviceCode(Loc, DiagID)
- : CUDA().DiagIfHostCode(Loc, DiagID);
-
- if (getLangOpts().SYCLIsDevice)
+
+ if (LangOpts.OpenMP) {
+if (LangOpts.OpenMPIsTargetDevice) {
+ return OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD);
+}
+
+SemaDiagnosticBuilder SDB = OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
+if (SDB.isDeferred()) {
+ FD->setInvalidDecl();
+}
+return SDB;
+ }
+
+ if (getLangOpts().CUDA) {
+if (getLangOpts().CUDAIsDevice) {
+ return CUDA().DiagIfDeviceCode(Loc, DiagID);
+}
+
+SemaDiagnosticBuilder SDB = CUDA().DiagIfHostCode(Loc, DiagID);
+if (SDB.isDeferred()) {
+ FD->setInvalidDecl();
+}
+return SDB;
+ }
+
+ if (getLangOpts().SYCLIsDevice) {
return SYCL().DiagIfDeviceCode(Loc, DiagID);
+ }
a-tarasyuk wrote:
@alexey-bataev removed. thanks
https://github.com/llvm/llvm-project/pull/147163
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
@@ -2092,18 +2092,36 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
}
Sema::SemaDiagnosticBuilder
-Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
+Sema::targetDiag(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD) {
FD = FD ? FD : getCurFunctionDecl();
- if (LangOpts.OpenMP)
-return LangOpts.OpenMPIsTargetDevice
- ? OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD)
- : OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
- if (getLangOpts().CUDA)
-return getLangOpts().CUDAIsDevice ? CUDA().DiagIfDeviceCode(Loc, DiagID)
- : CUDA().DiagIfHostCode(Loc, DiagID);
-
- if (getLangOpts().SYCLIsDevice)
+
+ if (LangOpts.OpenMP) {
+if (LangOpts.OpenMPIsTargetDevice) {
+ return OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD);
+}
+
+SemaDiagnosticBuilder SDB = OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
+if (SDB.isDeferred()) {
+ FD->setInvalidDecl();
+}
+return SDB;
+ }
+
+ if (getLangOpts().CUDA) {
+if (getLangOpts().CUDAIsDevice) {
+ return CUDA().DiagIfDeviceCode(Loc, DiagID);
+}
+
+SemaDiagnosticBuilder SDB = CUDA().DiagIfHostCode(Loc, DiagID);
+if (SDB.isDeferred()) {
+ FD->setInvalidDecl();
+}
+return SDB;
+ }
+
+ if (getLangOpts().SYCLIsDevice) {
return SYCL().DiagIfDeviceCode(Loc, DiagID);
+ }
alexey-bataev wrote:
Drop extra braces around one-line substatements
https://github.com/llvm/llvm-project/pull/147163
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk updated
https://github.com/llvm/llvm-project/pull/147163
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH 1/4] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 0..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clan
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk updated
https://github.com/llvm/llvm-project/pull/147163
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH 1/2] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 0..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clan
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: > Deferred errors only, though, right? Deferred unrecoverable errors, yes. > Do we know if there are any cases where we defer the diagnostic because we > may later decide it's not an error and thus codegen would be fine? As far as I can tell, targetDiag() works on a per-function basis: if a function is marked, that function is invalid. We can't recover later. The point is just that we want to allow inline functions containing certain invalid constructs if they aren't actually used in the current translation unit. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
AaronBallman wrote: > If a function has a deferred diagnostic, it should prevent codegen of that > function, yes. Deferred errors only, though, right? Do we know if there are any cases where we defer the diagnostic because we may later decide it's *not* an error and thus codegen would be fine? (I'm less familiar with deferred diagnostics, so I may be asking something silly.) https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk updated
https://github.com/llvm/llvm-project/pull/147163
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 0..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: I think calling targetDiag() should stop codegen. And if that works correctly, this patch is unnecessary. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
AaronBallman wrote: > My understanding is that "recoverable" in this context means we can actually > generate sensible IR for the construct. So no errors, except for warnings > promoted to errors (or certain errors which don't impact IRGen/CFG analysis). > And if that isn't what isUnrecoverable() is referring to, we should define a > new function which means that. Okay, I think that is what `isUnrecoverable()` is addressing. Thank you! Just to double-check, then you're happy with the state of the patch as-is because use of `StmtError` will result in the function being marked as invalid and the diagnostic is not recoverable? Or are there changes you'd like to see @a-tarasyuk make? https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: My understanding is that "recoverable" in this context means we can actually generate sensible IR for the construct. So no errors, except for warnings promoted to errors (or certain errors which don't impact IRGen/CFG analysis). And if that isn't what isUnrecoverable() is referring to, we should define a new function which means that. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: We shouldn't have invalid decls unless we've emitted an error. If we're making some decision like "this function is an error if it's used as a host function", we should probably be marking the FunctionDecl explicitly with that decision, and CodeGen shouldn't try to emit such a function. Also, the decision whether a function counts as "used" should probably be driven by Sema. Currently you don't get errors at all with -fsyntax-only. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
efriedma-quic wrote: I haven't really thought about what the right strategy is for diagnostics here, specifically, but it looks like the OpenMP diagnostic suppression isn't working correctly. If there's an error in a function, that should stop CodeGen from seeing the function at all. If it's crashing, that means we're doing codegen on invalid functions, which we don't want to do. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/AaronBallman approved this pull request. The changes look correct to me, but I added Eli and Alexey for some other opinions to be sure. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/alexey-bataev approved this pull request. https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Oleksandr T. (a-tarasyuk)
Changes
Fixes #140375
---
This patch addresses a crash in clang’s _codegen_ stage triggered by invalid
inline assembly statements under `-fopenmp`. The root cause was _deferred_
diagnostic emission (using `SemaDiagnosticBuilder::K_Deferred`) in _OpenMP_
target regions that may not be emitted, which allowed malformed asm statements
to reach codegen and cause a crash.
---
Full diff: https://github.com/llvm/llvm-project/pull/147163.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/lib/Sema/SemaStmtAsm.cpp (+14-20)
- (added) clang/test/OpenMP/openmp_asm.c (+28)
``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmStmt();
+return StmtError(
+targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto));
}
GCCAsmStmt *NS = CreateGCCAsmStmt();
diff --git a/clang/test/OpenMP/openmp_asm.c b/clang/test/OpenMP/openmp_asm.c
new file mode 100644
index 000
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk ready_for_review https://github.com/llvm/llvm-project/pull/147163 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
https://github.com/a-tarasyuk created
https://github.com/llvm/llvm-project/pull/147163
Fixes #140375
---
This patch addresses a crash in clang’s _codegen_ stage triggered by invalid
inline assembly statements under `-fopenmp`. The root cause was _deferred_
diagnostic emission (using `SemaDiagnosticBuilder::K_Deferred`) in _OpenMP_
target regions that may not be emitted, which allowed malformed asm statements
to reach codegen and cause a crash.
>From 4e0cf4e00d4cfd837e9dfd9e6aed88aca1de295a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk
Date: Sun, 6 Jul 2025 00:35:48 +0300
Subject: [PATCH] [Clang] fix crash in codegen caused by deferred asm
diagnostics under -fopenmp
---
clang/docs/ReleaseNotes.rst| 2 ++
clang/lib/Sema/SemaStmtAsm.cpp | 34 ++
clang/test/OpenMP/openmp_asm.c | 28
3 files changed, 44 insertions(+), 20 deletions(-)
create mode 100644 clang/test/OpenMP/openmp_asm.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a94c4bcd9980..dcf2ffe43edfd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -750,6 +750,8 @@ Bug Fixes in This Version
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr``
function. (#GH144264)
- Fixed a bug when use unicode character name in macro concatenation.
(#GH145240)
+- Fixed a crash caused by deferred diagnostics under ``-fopenmp``,
+ which resulted in passing invalid asm statements to codegen. (#GH140375)
Bug Fixes to Compiler Builtins
^^
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..b949178f6a938 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -309,10 +309,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, OutputName);
if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -378,9 +377,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
FeatureMap,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(Constraint),
Size)) {
- targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(OutputExpr->getBeginLoc(),
+ diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr());
}
}
@@ -399,10 +398,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
TargetInfo::ConstraintInfo Info(ConstraintStr, InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- targetDiag(Constraint->getBeginLoc(),
- diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
- return CreateGCCAsmStmt();
+ return StmtError(targetDiag(Constraint->getBeginLoc(),
+ diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr());
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -504,13 +502,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(ClobberExpr);
if (!Context.getTargetInfo().isValidClobber(Clobber)) {
- targetDiag(ClobberExpr->getBeginLoc(),
- diag::err_asm_unknown_register_name)
- << Clobber;
- return new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- constraints.data(), Exprs.data(), asmString, NumClobbers,
- clobbers.data(), NumLabels, RParenLoc);
+ return StmtError(targetDiag(ClobberExpr->getBeginLoc(),
+ diag::err_asm_unknown_register_name)
+ << Clobber);
}
if (Clobber == "unwind") {
@@ -520,8 +514,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
// Using unwind clobber and asm-goto together is not supported right now.
if (UnwindClobberLoc && NumLabels > 0) {
-targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);
-return CreateGCCAsmS
