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

Reply via email to