Skip to content

[Clang] fix crash in codegen caused by deferred asm diagnostics under -fopenmp #147163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/SemaBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/CodeGen/ModuleBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
36 changes: 25 additions & 11 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<FunctionDecl>(C)
? cast<FunctionDecl>(C)
: dyn_cast_or_null<FunctionDecl>(D);
FunctionDecl *FD = isa<FunctionDecl>(C) ? cast<FunctionDecl>(C)
: dyn_cast_or_null<FunctionDecl>(D);

auto CheckDeviceType = [&](QualType Ty) {
if (Ty->isDependentType())
Expand Down
28 changes: 28 additions & 0 deletions clang/test/OpenMP/openmp_asm.c
Original file line number Diff line number Diff line change
@@ -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;
}