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.taras...@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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits