[clang] [Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp (PR #147163)
Oleksandr T. via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 5 14:47:32 PDT 2025
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 <oleksandr.tarasiuk at outlook.com>
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 0000000000000..f2705d1a8803f
--- /dev/null
+++ b/clang/test/OpenMP/openmp_asm.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify=fopenmp -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -verify -emit-llvm -o - %s
+
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -x c++ -fopenmp -verify=fopenmp -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -x c++ -verify -emit-llvm -o - %s
+
+// fopenmp-no-diagnostics
+
+void t1(int *a, int *b) {
+ asm volatile("" : "+&r"(a) : ""(b)); // expected-error {{invalid input constraint '' in asm}}
+}
+
+void t2() {
+ asm ("nop" : : : "foo"); // expected-error {{unknown register name 'foo' in asm}}
+}
+
+void t3() {
+ asm goto ("" ::: "unwind" : label); // expected-error {{unwind clobber cannot be used with asm goto}}
+label:
+ ;
+}
+
+typedef int vec256 __attribute__((ext_vector_type(8)));
+vec256 t4() {
+ vec256 out;
+ asm("something %0" : "=y"(out)); // expected-error {{invalid output size for constraint '=y'}}
+ return out;
+}
More information about the cfe-commits
mailing list