diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e81a3d4976cf8..c199c31a6dc03 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -789,6 +789,8 @@ Bug Fixes in This Version declaration statements. Clang now emits a warning for these patterns. (#GH141659) - Fixed false positives for redeclaration errors of using enum in nested scopes. (#GH147495) +- 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/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b331acbe606b7..c59f48b621a05 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1110,10 +1110,10 @@ class Sema final : public SemaBase { } SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, - const FunctionDecl *FD = nullptr); + FunctionDecl *FD = nullptr); SemaDiagnosticBuilder targetDiag(SourceLocation Loc, const PartialDiagnostic &PD, - const FunctionDecl *FD = nullptr) { + FunctionDecl *FD = nullptr) { return targetDiag(Loc, PD.getDiagID(), FD) << PD; } diff --git a/clang/include/clang/Sema/SemaBase.h b/clang/include/clang/Sema/SemaBase.h index 550f530af72f5..c24db4d012413 100644 --- a/clang/include/clang/Sema/SemaBase.h +++ b/clang/include/clang/Sema/SemaBase.h @@ -138,6 +138,7 @@ class SemaBase { ~SemaDiagnosticBuilder(); bool isImmediate() const { return ImmediateDiag.has_value(); } + bool isDeferred() const { return PartialDiagId.has_value(); } /// Convertible to bool: True if we immediately emitted an error, false if /// we didn't emit an error or we created a deferred error. diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 8c1fee8c974f1..787ab30e0c92c 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -186,8 +186,12 @@ namespace { HandlingTopLevelDeclRAII HandlingDecl(*this); // Make sure to emit all elements of a Decl. - for (auto &I : DG) + for (auto &I : DG) { + if (I->isInvalidDecl()) { + continue; + } Builder->EmitTopLevelDecl(I); + } return true; } diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 56608e990fd50..3789af0d3d943 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -2092,15 +2092,30 @@ 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 (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); @@ -2138,9 +2153,8 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { // Try to associate errors with the lexical context, if that is a function, or // the value declaration otherwise. - const FunctionDecl *FD = isa(C) - ? cast(C) - : dyn_cast_or_null(D); + FunctionDecl *FD = isa(C) ? cast(C) + : dyn_cast_or_null(D); auto CheckDeviceType = [&](QualType Ty) { if (Ty->isDependentType()) 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; +}