https://github.com/pgerell created
https://github.com/llvm/llvm-project/pull/220316
Fixes #147515.
Depends on #220058. The first commit is from that PR, only the second belongs
to this
one. It is needed because `OpenMP/target_ast_print.cpp` fails without it once
these
diagnostics start being emitted.
## The bug
```c++
// t.cpp
void foo();
int f() {
try {
foo();
} catch (...) {
return 1;
}
return 0;
}
```
```
$ clang++ -fsyntax-only -fno-exceptions t.cpp
t.cpp:4:3: error: cannot use 'try' with exceptions disabled
$ clang++ -fsyntax-only -fno-exceptions -fopenmp t.cpp
$ clang++ -fsyntax-only -fno-exceptions -fopenmp-simd t.cpp
$ clang++ -fsyntax-only -fno-exceptions -fopenmp
-fopenmp-targets=x86_64-unknown-linux-gnu t.cpp
t.cpp:4:3: error: cannot use 'try' with exceptions disabled
```
Adding `-fopenmp` drops the error. Adding an offload target brings it back.
## Why
`Sema::targetDiag` sends the diagnostic to `SemaOpenMP::diagIfOpenMPHostCode`,
which
queues it as `K_Deferred`. Nothing flushes that queue, because
`Sema::ActOnFinishFunctionBody` only records a function for deferred-diagnostic
checking
when
```c++
LangOpts.isTargetDevice() || LangOpts.CUDA ||
(LangOpts.OpenMP && !LangOpts.OMPTargetTriples.empty())
```
With plain `-fopenmp` there are no target triples, so nothing is recorded and
`Sema::emitDeferredDiags` returns early on
`DeclsToCheckForDeferredDiags.empty()`. The
deferral itself is fine, the flush is missing.
Every diagnostic routed through `targetDiag` is affected, not just this one.
For inline
asm it is worse than a missing error, because `SemaStmtAsm.cpp` continues with
`return CreateGCCAsmStmt()` afterwards, so an invalid constraint reaches
CodeGen:
```c++
void g(int x) { __asm__("nop" : "=@"(x)); }
```
```
$ clang++ -fopenmp -c a.cpp
clang/lib/CodeGen/CGStmt.cpp:2912: Assertion `IsValid && "Failed to parse
output constraint"' failed.
```
`"Failed to parse input constraint"` in the same file and
`isValidGCCRegisterName(Name) && "Invalid register passed in"` in
`TargetInfo.cpp` are
reachable the same way.
## The fix
Two changes. Neither is sufficient alone.
`ActOnFinishFunctionBody` now records functions on any OpenMP compilation.
`getEmissionStatus(FD, /*Final=*/true)` still reports `OMPDiscarded` for
`device_type(nohost)`, so functions the host does not emit keep their
diagnostics
suppressed, including when the `declare target` comes after the body.
`Sema::targetDiag` no longer routes `-fopenmp-simd` into the deferral path.
There is no
device compilation to defer for, and `declare target` is ignored, so a `nohost`
function
is in fact emitted on the host under `-fopenmp-simd` while its diagnostics were
being
suppressed as if it were not.
Both are needed because `-fopenmp` does not emit functions eagerly
(`CodeGenModule::MayBeEmittedEagerly`, `OpenMP >= 50 && !OpenMPSimd`), so the
end-of-TU
flush still runs before CodeGen. Under `-fopenmp-simd` the function is emitted
during
parsing and CodeGen asserts first, so the diagnostic has to be immediate.
## Tests
`check-clang` is clean. Three existing tests had the old behaviour written into
them:
* `CodeGen/X86/mmx-inline-asm-error.c`, whose `-fopenmp` RUN line expected
different
diagnostics from its default run
* `OpenMP/declare_target_messages.cpp`, where only the RUN lines passing
`-fopenmp-targets` expected the `device_type(nohost)` diagnostics
* `OpenMP/target_ast_print.cpp`, which needs #220058 and is unchanged here
New tests: `OpenMP/host_exceptions_messages.cpp`, `OpenMP/host_asm_messages.c`.
>From 4208f4c6e8f7245e241962963d90eb42842cb53f Mon Sep 17 00:00:00 2001
From: Peter Gerell <[email protected]>
Date: Mon, 31 Aug 2026 17:49:29 +0200
Subject: [PATCH 1/2] [clang][OpenMP] Keep 'requires' directives read from an
AST file
---
clang/docs/ReleaseNotes.md | 4 +++
clang/include/clang/Sema/SemaOpenMP.h | 6 ++++
.../include/clang/Serialization/ASTBitCodes.h | 3 ++
clang/include/clang/Serialization/ASTReader.h | 3 ++
clang/include/clang/Serialization/ASTWriter.h | 1 +
clang/lib/Sema/SemaOpenMP.cpp | 12 ++++++++
clang/lib/Serialization/ASTReader.cpp | 13 +++++++++
clang/lib/Serialization/ASTWriter.cpp | 16 +++++++++++
clang/test/OpenMP/requires_module.cpp | 28 +++++++++++++++++++
clang/test/OpenMP/requires_pch.cpp | 24 ++++++++++++++++
10 files changed, 110 insertions(+)
create mode 100644 clang/test/OpenMP/requires_module.cpp
create mode 100644 clang/test/OpenMP/requires_pch.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 32ee602dc8472..3bf5e982fd6ac 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -733,6 +733,10 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was
renamed to `alpha.core.Use
### OpenMP Support
+- Fixed an OpenMP `requires` directive losing its effect on semantic checks
when it was
+ read from a PCH or module, which caused spurious errors such as `device`
clause with
+ the `ancestor` modifier requiring `reverse_offload`.
+
- Added parsing and semantic support for `dims` modifier in `num_teams`,
`thread_limit` and `num_threads` clauses for OpenMP 6.1 or later.
- Map-type-modifying modifiers applied to a list item with a user-defined
mapper
diff --git a/clang/include/clang/Sema/SemaOpenMP.h
b/clang/include/clang/Sema/SemaOpenMP.h
index a5f357c15f5c4..c799254632829 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -259,6 +259,12 @@ class SemaOpenMP : public SemaBase {
/// Called on well-formed '#pragma omp requires'.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
ArrayRef<OMPClause *>
ClauseList);
+
+ /// Registers a 'requires' directive deserialized from an AST file.
+ void addRequiresDecl(OMPRequiresDecl *D);
+
+ /// The 'requires' directives seen so far in this translation unit.
+ ArrayRef<const OMPRequiresDecl *> getRequiresDecls() const;
/// Check restrictions on Requires directive
OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc,
ArrayRef<OMPClause *> Clauses);
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h
b/clang/include/clang/Serialization/ASTBitCodes.h
index 6a52a9e4fa780..08076b4a209ce 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -747,6 +747,9 @@ enum ASTRecordTypes {
/// Record that encodes the number of submodules, their base ID in the AST
/// file, and for each module the relative bit offset into the stream.
SUBMODULE_METADATA = 80,
+
+ /// Record code for the OpenMP 'requires' directives seen in the TU.
+ OMP_REQUIRES_DECLS = 81,
};
/// Record types used within a source manager block.
diff --git a/clang/include/clang/Serialization/ASTReader.h
b/clang/include/clang/Serialization/ASTReader.h
index 0c8c92feee176..c06d70a340ad3 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1052,6 +1052,9 @@ class ASTReader : public ExternalPreprocessorSource,
/// The IDs of all decls with function effects to be checked.
SmallVector<GlobalDeclID> DeclsWithEffectsToVerify;
+ /// OpenMP 'requires' directives read from the AST file.
+ SmallVector<GlobalDeclID> OpenMPRequiresDecls;
+
/// The RISC-V intrinsic pragma(including RVV, SiFive and Andes).
SmallVector<bool, 3> RISCVVecIntrinsicPragma;
diff --git a/clang/include/clang/Serialization/ASTWriter.h
b/clang/include/clang/Serialization/ASTWriter.h
index 95ae8a6ba8c74..f69646d1ca0a9 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -648,6 +648,7 @@ class ASTWriter : public ASTDeserializationListener,
void WritePackPragmaOptions(Sema &SemaRef);
void WriteFloatControlPragmaOptions(Sema &SemaRef);
void WriteDeclsWithEffectsToVerify(Sema &SemaRef);
+ void WriteOpenMPRequiresDecls(Sema &SemaRef);
void WriteModuleFileExtension(Sema &SemaRef,
ModuleFileExtensionWriter &Writer);
void WriteRISCVIntrinsicPragmas(Sema &SemaRef);
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 7ddda157dad9d..98796397a1c1e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -678,6 +678,10 @@ class DSAStackTy {
/// Add requires decl to internal vector
void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
+ ArrayRef<const OMPRequiresDecl *> getRequiresDecls() const {
+ return RequiresDecls;
+ }
+
/// Checks if the defined 'requires' directive has specified type of clause.
template <typename ClauseType> bool hasRequiresDeclWithClause() const {
return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
@@ -2069,6 +2073,14 @@ void SemaOpenMP::InitDataSharingAttributesStack() {
#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
+void SemaOpenMP::addRequiresDecl(OMPRequiresDecl *D) {
+ DSAStack->addRequiresDecl(D);
+}
+
+ArrayRef<const OMPRequiresDecl *> SemaOpenMP::getRequiresDecls() const {
+ return DSAStack->getRequiresDecls();
+}
+
void SemaOpenMP::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
void SemaOpenMP::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
diff --git a/clang/lib/Serialization/ASTReader.cpp
b/clang/lib/Serialization/ASTReader.cpp
index a9c230d767c50..8336d66c2a00c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -26,6 +26,7 @@
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
@@ -81,6 +82,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaObjC.h"
+#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaRISCV.h"
#include "clang/Sema/Weak.h"
#include "clang/Serialization/ASTBitCodes.h"
@@ -4480,6 +4482,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
DeclsWithEffectsToVerify.push_back(ReadDeclID(F, Record, I));
break;
+ case OMP_REQUIRES_DECLS:
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ OpenMPRequiresDecls.push_back(ReadDeclID(F, Record, I));
+ break;
+
case OPENCL_EXTENSIONS:
for (unsigned I = 0, E = Record.size(); I != E; ) {
auto Name = ReadString(Record, I);
@@ -9293,6 +9300,12 @@ void ASTReader::InitializeSema(Sema &S) {
void ASTReader::UpdateSema() {
assert(SemaObj && "no Sema to update");
+ // Runs after every AST file is loaded, not just the first, so that a
+ // 'requires' directive coming from a module is picked up too.
+ for (GlobalDeclID ID : OpenMPRequiresDecls)
+ SemaObj->OpenMP().addRequiresDecl(cast<OMPRequiresDecl>(GetDecl(ID)));
+ OpenMPRequiresDecls.clear();
+
// Load the offsets of the declarations that Sema references.
// They will be lazily deserialized when needed.
if (!SemaDeclRefs.empty()) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp
b/clang/lib/Serialization/ASTWriter.cpp
index de985b770cb01..522ecc876e3d3 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -24,6 +24,7 @@
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
@@ -70,6 +71,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaObjC.h"
+#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaRISCV.h"
#include "clang/Sema/Weak.h"
#include "clang/Serialization/ASTBitCodes.h"
@@ -5274,6 +5276,19 @@ void ASTWriter::WriteDeclsWithEffectsToVerify(Sema
&SemaRef) {
Stream.EmitRecord(DECLS_WITH_EFFECTS_TO_VERIFY, Record);
}
+/// Write the OpenMP 'requires' directives seen in this translation unit.
+void ASTWriter::WriteOpenMPRequiresDecls(Sema &SemaRef) {
+ if (!SemaRef.getLangOpts().OpenMP)
+ return;
+ ArrayRef<const OMPRequiresDecl *> Decls =
SemaRef.OpenMP().getRequiresDecls();
+ if (Decls.empty())
+ return;
+ RecordData Record;
+ for (const auto *D : Decls)
+ AddDeclRef(D, Record);
+ Stream.EmitRecord(OMP_REQUIRES_DECLS, Record);
+}
+
void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
ModuleFileExtensionWriter &Writer) {
// Enter the extension block.
@@ -6349,6 +6364,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr,
StringRef isysroot,
WritePackPragmaOptions(*SemaPtr);
WriteFloatControlPragmaOptions(*SemaPtr);
WriteDeclsWithEffectsToVerify(*SemaPtr);
+ WriteOpenMPRequiresDecls(*SemaPtr);
}
// Some simple statistics
diff --git a/clang/test/OpenMP/requires_module.cpp
b/clang/test/OpenMP/requires_module.cpp
new file mode 100644
index 0000000000000..7e7034473b224
--- /dev/null
+++ b/clang/test/OpenMP/requires_module.cpp
@@ -0,0 +1,28 @@
+// RUN: rm -rf %t && split-file %s %t
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -fmodules -fmodule-name=rev \
+// RUN: -x c++ -emit-module %t/module.modulemap -o %t/rev.pcm
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -fmodules
-fmodule-file=%t/rev.pcm \
+// RUN: -verify -fsyntax-only %t/use.cpp
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -fopenmp-targets=x86_64
-triple x86_64 \
+// RUN: -fmodules -fmodule-name=rev -x c++ -emit-module %t/module.modulemap
-o %t/rev2.pcm
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -fopenmp-targets=x86_64
-triple x86_64 \
+// RUN: -fmodules -fmodule-file=%t/rev2.pcm -verify -fsyntax-only %t/use.cpp
+
+// A 'requires' directive read from a module must keep its effect on the
+// translation unit importing it.
+
+//--- module.modulemap
+module rev { header "rev.h" export * }
+
+//--- rev.h
+#pragma omp requires reverse_offload
+void foo();
+
+//--- use.cpp
+#include "rev.h"
+
+// expected-no-diagnostics
+void bar(int argc) {
+#pragma omp target device(ancestor : argc)
+ foo();
+}
diff --git a/clang/test/OpenMP/requires_pch.cpp
b/clang/test/OpenMP/requires_pch.cpp
new file mode 100644
index 0000000000000..7f1e76252ac6c
--- /dev/null
+++ b/clang/test/OpenMP/requires_pch.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -std=c++11
-emit-pch -o %t %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -std=c++11
-include-pch %t -fsyntax-only %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11
-emit-pch -o %t %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -std=c++11
-include-pch %t -fsyntax-only %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51
-fopenmp-targets=x86_64 \
+// RUN: -triple x86_64 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51
-fopenmp-targets=x86_64 \
+// RUN: -triple x86_64 -std=c++11 -include-pch %t -fsyntax-only %s
+
+// expected-no-diagnostics
+
+// A 'requires' directive read from an AST file must keep its effect on the
+// translation unit including it.
+
+#ifndef HEADER
+#define HEADER
+#pragma omp requires reverse_offload
+void foo();
+#else
+void bar(int argc) {
+#pragma omp target device(ancestor : argc)
+ foo();
+}
+#endif
>From 93fd1c64ad98b5766ddcb7c24289921786d44b0e Mon Sep 17 00:00:00 2001
From: Peter Gerell <[email protected]>
Date: Mon, 31 Aug 2026 17:49:48 +0200
Subject: [PATCH 2/2] [clang][OpenMP] Emit host diagnostics that were deferred
and never flushed
---
clang/docs/ReleaseNotes.md | 11 ++++++
clang/lib/Sema/Sema.cpp | 4 +-
clang/lib/Sema/SemaDecl.cpp | 3 +-
clang/test/CodeGen/X86/mmx-inline-asm-error.c | 7 +---
clang/test/OpenMP/declare_target_messages.cpp | 12 +++---
clang/test/OpenMP/host_asm_messages.c | 10 +++++
.../test/OpenMP/host_exceptions_messages.cpp | 37 +++++++++++++++++++
7 files changed, 70 insertions(+), 14 deletions(-)
create mode 100644 clang/test/OpenMP/host_asm_messages.c
create mode 100644 clang/test/OpenMP/host_exceptions_messages.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3bf5e982fd6ac..c1001464b5851 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -101,6 +101,10 @@ features cannot lower the translation-unit ABI level;
### Clang Frontend Potentially Breaking Changes
- Templight support has been removed.
+- Diagnostics that a host OpenMP compilation deferred are now emitted instead
of being
+ silently dropped when no offload target is configured. Code accepted by
`-fopenmp` or
+ `-fopenmp-simd` may now be rejected, matching a compilation without those
flags. Most
+ notably `try`/`throw` with exceptions disabled is diagnosed again.
(#GH147515)
### Clang Python Bindings Potentially Breaking Changes
@@ -733,6 +737,13 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was
renamed to `alpha.core.Use
### OpenMP Support
+- Fixed a bug where a host OpenMP compilation never emitted its deferred
+ diagnostics unless an offload target was configured, so errors such as using
+ `try`/`throw` with exceptions disabled were silently dropped, and an invalid
inline
+ asm constraint reached CodeGen and crashed it. (#GH147515)
+- Fixed `-fopenmp-simd` deferring diagnostics as if it were a device
compilation. It has
+ no device compilation and ignores `declare target`, so its diagnostics are
now emitted
+ directly.
- Fixed an OpenMP `requires` directive losing its effect on semantic checks
when it was
read from a PCH or module, which caused spurious errors such as `device`
clause with
the `ancestor` modifier requiring `reverse_offload`.
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 21f71d7f8b40e..c3532a09961fc 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2261,7 +2261,9 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
Sema::SemaDiagnosticBuilder
Sema::targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD) {
FD = FD ? FD : getCurFunctionDecl();
- if (LangOpts.OpenMP)
+ // -fopenmp-simd has no device compilation and ignores 'declare target', so
+ // there is nothing to defer for.
+ if (LangOpts.OpenMP && !LangOpts.OpenMPSimd)
return LangOpts.OpenMPIsTargetDevice
? OpenMP().diagIfOpenMPDeviceCode(Loc, DiagID, FD)
: OpenMP().diagIfOpenMPHostCode(Loc, DiagID, FD);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 07c6157ab8f31..41a1aa6913fec 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -17335,8 +17335,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt
*Body, bool IsInstantiation,
DiscardCleanupsInEvaluationContext();
}
- if (FD && (LangOpts.isTargetDevice() || LangOpts.CUDA ||
- (LangOpts.OpenMP && !LangOpts.OMPTargetTriples.empty()))) {
+ if (FD && (LangOpts.isTargetDevice() || LangOpts.CUDA || LangOpts.OpenMP)) {
auto ES = getEmissionStatus(FD);
if (ES == Sema::FunctionEmissionStatus::Emitted ||
ES == Sema::FunctionEmissionStatus::Unknown)
diff --git a/clang/test/CodeGen/X86/mmx-inline-asm-error.c
b/clang/test/CodeGen/X86/mmx-inline-asm-error.c
index 7f7f53a553057..da5b60fdac64c 100644
--- a/clang/test/CodeGen/X86/mmx-inline-asm-error.c
+++ b/clang/test/CodeGen/X86/mmx-inline-asm-error.c
@@ -1,16 +1,13 @@
// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only %s
-// RUN: %clang_cc1 -verify=omp -triple x86_64-unknown-unknown -emit-llvm-only
-fopenmp %s
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only
-fopenmp %s
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only
-fopenmp-simd %s
typedef int vec256 __attribute__((ext_vector_type(8)));
-// omp-warning@+2 {{AVX vector return of type 'vec256' (vector of 8 'int'
values) without 'avx' enabled changes the ABI}}
-// omp-warning@+1 {{AVX vector argument of type 'vec256' (vector of 8 'int'
values) without 'avx' enabled changes the ABI}}
vec256 foo(vec256 in) {
vec256 out;
asm("something %0" : : "y"(in)); // expected-error {{invalid input size for
constraint 'y'}}
- // omp-error@+1 {{invalid type 'vec256' (vector of 8 'int' values) in asm
input for constraint 'y'}}
asm("something %0" : "=y"(out)); // expected-error {{invalid output size for
constraint '=y'}}
- // omp-error@+1 {{invalid type 'vec256' (vector of 8 'int' values) in asm
input for constraint 'y'}}
asm("something %0, %0" : "+y"(out)); // expected-error {{invalid output size
for constraint '+y'}}
return out;
diff --git a/clang/test/OpenMP/declare_target_messages.cpp
b/clang/test/OpenMP/declare_target_messages.cpp
index 6fe477755dbe7..62a12d40b7271 100644
--- a/clang/test/OpenMP/declare_target_messages.cpp
+++ b/clang/test/OpenMP/declare_target_messages.cpp
@@ -21,16 +21,16 @@
// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp60,omp52-or-later,ompvar,omp5-or-later,omp5-or-later-var
%{openmp60_simd} -fopenmp-is-target-device %{target_mac} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp45,omp45-to-51,omp45-to-51-var,omp45-to-51-clause
-fopenmp-version=45 -fopenmp-simd %{limit} -o - %s
-// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -o - %s
-// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -DTESTEND=1 -o - %s
-// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -I%S/Inputs -DTESTENDINC=1 -o - %s
-// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51
-fopenmp-simd %{limit} -o - %s
+// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -o - %s
+// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -DTESTEND=1 -o - %s
+// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -I%S/Inputs -DTESTENDINC=1 -o - %s
+// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51
-fopenmp-simd %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp52,omp52-or-later,ompvar,omp5-or-later,omp5-or-later-var
%{openmp52} -DVERBOSE_MODE=1 %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp60,omp52-or-later,ompvar,omp5-or-later,omp5-or-later-var
%{openmp60} -DVERBOSE_MODE=1 %{limit} -o - %s
-// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51
%{openmp50} %{limit} -o - %s
-// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -o - %s
+// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51
%{openmp50} %{limit} -o - %s
+// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51
-fopenmp %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac}
-verify=expected,omp60,omp52-or-later,ompvar,omp5-or-later,omp5-or-later-var
%{openmp60} %{limit} -o - %s
#pragma omp begin declare target
diff --git a/clang/test/OpenMP/host_asm_messages.c
b/clang/test/OpenMP/host_asm_messages.c
new file mode 100644
index 0000000000000..40fc2e3b7651a
--- /dev/null
+++ b/clang/test/OpenMP/host_asm_messages.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only %s
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only
-fopenmp %s
+// RUN: %clang_cc1 -verify -triple x86_64-unknown-unknown -emit-llvm-only
-fopenmp-simd %s
+
+// An invalid asm constraint must be diagnosed rather than reaching CodeGen,
+// which cannot handle it.
+
+void f(void) {
+ __asm__("nop" ::: "no_such_register"); // expected-error {{unknown register
name 'no_such_register' in asm}}
+}
diff --git a/clang/test/OpenMP/host_exceptions_messages.cpp
b/clang/test/OpenMP/host_exceptions_messages.cpp
new file mode 100644
index 0000000000000..7a176f4df5f8a
--- /dev/null
+++ b/clang/test/OpenMP/host_exceptions_messages.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -verify=expected,host -fopenmp -fsyntax-only %s
+// RUN: %clang_cc1 -verify=expected,simd -fopenmp-simd -fsyntax-only %s
+// RUN: %clang_cc1 -verify=expected,host -fopenmp -fopenmp-targets=x86_64
-triple x86_64 -fsyntax-only %s
+
+// Exceptions are disabled, so a host compilation must diagnose 'try' and
'throw'
+// whether or not an offload target is configured.
+
+void foo();
+
+void bar() {
+ try { // expected-error {{cannot use 'try' with exceptions disabled}}
+ foo();
+ } catch (...) {
+ }
+}
+
+void baz(bool b) {
+ if (b)
+ throw 1; // expected-error {{cannot use 'throw' with exceptions disabled}}
+}
+
+// A 'device_type(nohost)' function is not emitted by a host -fopenmp
compilation, but
+// -fopenmp-simd ignores 'declare target' and does emit it.
+#pragma omp begin declare target device_type(nohost)
+void devonly() {
+ try { // simd-error {{cannot use 'try' with exceptions disabled}}
+ foo();
+ } catch (...) {
+ }
+}
+#pragma omp end declare target
+
+// Same, but marked 'nohost' only after the body has been parsed.
+void late() {
+ throw 1; // simd-error {{cannot use 'throw' with exceptions disabled}}
+}
+#pragma omp declare target to(late) device_type(nohost)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits