[clang] 725bb5b - [OpenMP][Clang] Parsing/Sema support for `use_device_ptr(fb_preserve/fb_nullify)`. (2/4) (#170578)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 16 10:58:23 PST 2026
Author: Abhinav Gaba
Date: 2026-01-16T10:58:19-08:00
New Revision: 725bb5b9feb690657d9dc69dfc55aeb1249b4721
URL: https://github.com/llvm/llvm-project/commit/725bb5b9feb690657d9dc69dfc55aeb1249b4721
DIFF: https://github.com/llvm/llvm-project/commit/725bb5b9feb690657d9dc69dfc55aeb1249b4721.diff
LOG: [OpenMP][Clang] Parsing/Sema support for `use_device_ptr(fb_preserve/fb_nullify)`. (2/4) (#170578)
Depends on #169603.
This is the `use_device_ptr` counterpart of #168905.
With OpenMP 6.1, a `fallback` modifier can be specified on the
`use_device_ptr` clause to control the behavior when a pointer lookup
fails, i.e. there is no device pointer to translate into.
The default is `fb_preserve` (i.e. retain the original pointer), while
`fb_nullify` means: use `nullptr` as the translated pointer.
Dependent PR: #173930.
Added:
clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp
clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp
Modified:
clang/include/clang/AST/OpenMPClause.h
clang/include/clang/Basic/OpenMPKinds.def
clang/include/clang/Basic/OpenMPKinds.h
clang/include/clang/Sema/SemaOpenMP.h
clang/lib/AST/OpenMPClause.cpp
clang/lib/Basic/OpenMPKinds.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 2ef363952f67f..e6b9c47a90c76 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -8061,6 +8061,13 @@ class OMPUseDevicePtrClause final
friend OMPVarListClause;
friend TrailingObjects;
+ /// Fallback modifier for the clause.
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier =
+ OMPC_USE_DEVICE_PTR_FALLBACK_unknown;
+
+ /// Location of the fallback modifier.
+ SourceLocation FallbackModifierLoc;
+
/// Build clause with number of variables \a NumVars.
///
/// \param Locs Locations needed to build a mappable clause. It includes 1)
@@ -8071,10 +8078,15 @@ class OMPUseDevicePtrClause final
/// NumUniqueDeclarations: number of unique base declarations in this clause;
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
- explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs,
- const OMPMappableExprListSizeTy &Sizes)
- : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) {
- }
+ /// \param FallbackModifier The fallback modifier for the clause.
+ /// \param FallbackModifierLoc Location of the fallback modifier.
+ explicit OMPUseDevicePtrClause(
+ const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes,
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier,
+ SourceLocation FallbackModifierLoc)
+ : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes),
+ FallbackModifier(FallbackModifier),
+ FallbackModifierLoc(FallbackModifierLoc) {}
/// Build an empty clause.
///
@@ -8127,6 +8139,14 @@ class OMPUseDevicePtrClause final
return {getPrivateCopies().end(), varlist_size()};
}
+ /// Set the fallback modifier for the clause.
+ void setFallbackModifier(OpenMPUseDevicePtrFallbackModifier M) {
+ FallbackModifier = M;
+ }
+
+ /// Set the location of the fallback modifier.
+ void setFallbackModifierLoc(SourceLocation Loc) { FallbackModifierLoc = Loc; }
+
public:
/// Creates clause with a list of variables \a Vars.
///
@@ -8139,11 +8159,15 @@ class OMPUseDevicePtrClause final
/// \param Inits Expressions referring to private copy initializers.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
+ /// \param FallbackModifier The fallback modifier for the clause.
+ /// \param FallbackModifierLoc Location of the fallback modifier.
static OMPUseDevicePtrClause *
Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars,
ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists);
+ MappableExprComponentListsRef ComponentLists,
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier,
+ SourceLocation FallbackModifierLoc);
/// Creates an empty clause with the place for \a NumVars variables.
///
@@ -8156,6 +8180,14 @@ class OMPUseDevicePtrClause final
static OMPUseDevicePtrClause *
CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);
+ /// Get the fallback modifier for the clause.
+ OpenMPUseDevicePtrFallbackModifier getFallbackModifier() const {
+ return FallbackModifier;
+ }
+
+ /// Get the location of the fallback modifier.
+ SourceLocation getFallbackModifierLoc() const { return FallbackModifierLoc; }
+
using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
using private_copies_range = llvm::iterator_range<private_copies_iterator>;
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 4f7858097a0d4..3b79b940a1253 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -113,6 +113,9 @@
#ifndef OPENMP_NEED_DEVICE_PTR_KIND
#define OPENMP_NEED_DEVICE_PTR_KIND(Name)
#endif
+#ifndef OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER
+#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name)
+#endif
// Static attributes for 'schedule' clause.
OPENMP_SCHEDULE_KIND(static)
@@ -285,6 +288,10 @@ OPENMP_THREADSET_KIND(omp_team)
OPENMP_NEED_DEVICE_PTR_KIND(fb_nullify)
OPENMP_NEED_DEVICE_PTR_KIND(fb_preserve)
+// OpenMP 6.1 modifiers for 'use_device_ptr' clause.
+OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(fb_nullify)
+OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(fb_preserve)
+
#undef OPENMP_NUMTASKS_MODIFIER
#undef OPENMP_NUMTHREADS_MODIFIER
#undef OPENMP_DYN_GROUPPRIVATE_MODIFIER
@@ -319,3 +326,4 @@ OPENMP_NEED_DEVICE_PTR_KIND(fb_preserve)
#undef OPENMP_THREADSET_KIND
#undef OPENMP_TRANSPARENT_KIND
#undef OPENMP_NEED_DEVICE_PTR_KIND
+#undef OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 3b088b3efd998..4e83bfcd0128b 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -218,6 +218,14 @@ enum OpenMPNeedDevicePtrModifier {
OMPC_NEED_DEVICE_PTR_unknown,
};
+/// OpenMP 6.1 use_device_ptr fallback modifier
+enum OpenMPUseDevicePtrFallbackModifier {
+#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) \
+ OMPC_USE_DEVICE_PTR_FALLBACK_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_USE_DEVICE_PTR_FALLBACK_unknown,
+};
+
/// OpenMP bindings for the 'bind' clause.
enum OpenMPBindClauseKind {
#define OPENMP_BIND_KIND(Name) OMPC_BIND_##Name,
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index c932e8f9c1a52..7853f29f98c25 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1176,8 +1176,8 @@ class SemaOpenMP : public SemaBase {
SourceLocation RLoc;
CXXScopeSpec ReductionOrMapperIdScopeSpec;
DeclarationNameInfo ReductionOrMapperId;
- int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or
- ///< lastprivate clause.
+ int ExtraModifier = -1; ///< Additional modifier for linear, map, depend,
+ ///< lastprivate, or use_device_ptr clause.
int OriginalSharingModifier = 0; // Default is shared
int NeedDevicePtrModifier = 0;
SourceLocation NeedDevicePtrModifierLoc;
@@ -1369,8 +1369,10 @@ class SemaOpenMP : public SemaBase {
ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> UnresolvedMappers = {});
/// Called on well-formed 'use_device_ptr' clause.
- OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
- const OMPVarListLocTy &Locs);
+ OMPClause *ActOnOpenMPUseDevicePtrClause(
+ ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier,
+ SourceLocation FallbackModifierLoc);
/// Called on well-formed 'use_device_addr' clause.
OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
const OMPVarListLocTy &Locs);
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index fc364418ce51c..62d78660570de 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -1442,7 +1442,9 @@ OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists) {
+ MappableExprComponentListsRef ComponentLists,
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier,
+ SourceLocation FallbackModifierLoc) {
OMPMappableExprListSizeTy Sizes;
Sizes.NumVars = Vars.size();
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
@@ -1466,7 +1468,8 @@ OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
Sizes.NumComponents));
- OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
+ OMPUseDevicePtrClause *Clause = new (Mem)
+ OMPUseDevicePtrClause(Locs, Sizes, FallbackModifier, FallbackModifierLoc);
Clause->setVarRefs(Vars);
Clause->setPrivateCopies(PrivateVars);
@@ -2760,7 +2763,15 @@ void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
if (!Node->varlist_empty()) {
OS << "use_device_ptr";
- VisitOMPClauseList(Node, '(');
+ if (Node->getFallbackModifier() != OMPC_USE_DEVICE_PTR_FALLBACK_unknown) {
+ OS << "("
+ << getOpenMPSimpleClauseTypeName(OMPC_use_device_ptr,
+ Node->getFallbackModifier())
+ << ":";
+ VisitOMPClauseList(Node, ' ');
+ } else {
+ VisitOMPClauseList(Node, '(');
+ }
OS << ")";
}
}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index c7bffe2d0d18e..2c693b1958ee7 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -238,6 +238,16 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
return OMPC_NUMTHREADS_unknown;
return Type;
}
+ case OMPC_use_device_ptr: {
+ unsigned Type = llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) \
+ .Case(#Name, OMPC_USE_DEVICE_PTR_FALLBACK_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_USE_DEVICE_PTR_FALLBACK_unknown);
+ if (LangOpts.OpenMP < 61)
+ return OMPC_USE_DEVICE_PTR_FALLBACK_unknown;
+ return Type;
+ }
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_groupprivate:
@@ -280,7 +290,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_nogroup:
case OMPC_hint:
case OMPC_uniform:
- case OMPC_use_device_ptr:
case OMPC_use_device_addr:
case OMPC_is_device_ptr:
case OMPC_has_device_addr:
@@ -608,6 +617,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'threadset' clause modifier");
+ case OMPC_use_device_ptr:
+ switch (Type) {
+ case OMPC_USE_DEVICE_PTR_FALLBACK_unknown:
+ return "unknown";
+#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) \
+ case OMPC_USE_DEVICE_PTR_FALLBACK_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'use_device_ptr' clause modifier");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_groupprivate:
@@ -650,7 +669,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_nogroup:
case OMPC_hint:
case OMPC_uniform:
- case OMPC_use_device_ptr:
case OMPC_use_device_addr:
case OMPC_is_device_ptr:
case OMPC_has_device_addr:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 45f0497aeb116..ec62df83a203e 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -5056,6 +5056,23 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
"adjust-op");
}
+ } else if (Kind == OMPC_use_device_ptr) {
+ // Handle optional fallback modifier for use_device_ptr clause.
+ // use_device_ptr([fb_preserve | fb_nullify :] list)
+ Data.ExtraModifier = OMPC_USE_DEVICE_PTR_FALLBACK_unknown;
+ if (getLangOpts().OpenMP >= 61 && Tok.is(tok::identifier)) {
+ auto FallbackModifier = static_cast<OpenMPUseDevicePtrFallbackModifier>(
+ getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
+ if (FallbackModifier != OMPC_USE_DEVICE_PTR_FALLBACK_unknown) {
+ Data.ExtraModifier = FallbackModifier;
+ Data.ExtraModifierLoc = Tok.getLocation();
+ ConsumeToken();
+ if (Tok.is(tok::colon))
+ Data.ColonLoc = ConsumeToken();
+ else
+ Diag(Tok, diag::err_modifier_expected_colon) << "fallback";
+ }
+ }
}
bool IsComma =
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 246a2c9c90b1b..084abaf487bb8 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -18818,7 +18818,13 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
VarList, Locs);
break;
case OMPC_use_device_ptr:
- Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
+ assert(0 <= Data.ExtraModifier &&
+ Data.ExtraModifier <= OMPC_USE_DEVICE_PTR_FALLBACK_unknown &&
+ "Unexpected use_device_ptr fallback modifier.");
+ Res = ActOnOpenMPUseDevicePtrClause(
+ VarList, Locs,
+ static_cast<OpenMPUseDevicePtrFallbackModifier>(Data.ExtraModifier),
+ Data.ExtraModifierLoc);
break;
case OMPC_use_device_addr:
Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
@@ -24635,9 +24641,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPFromClause(
MapperId);
}
-OMPClause *
-SemaOpenMP::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
- const OMPVarListLocTy &Locs) {
+OMPClause *SemaOpenMP::ActOnOpenMPUseDevicePtrClause(
+ ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier,
+ SourceLocation FallbackModifierLoc) {
MappableVarListInfo MVLI(VarList);
SmallVector<Expr *, 8> PrivateCopies;
SmallVector<Expr *, 8> Inits;
@@ -24718,7 +24725,8 @@ SemaOpenMP::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
return OMPUseDevicePtrClause::Create(
getASTContext(), Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
- MVLI.VarBaseDeclarations, MVLI.VarComponents);
+ MVLI.VarBaseDeclarations, MVLI.VarComponents, FallbackModifier,
+ FallbackModifierLoc);
}
OMPClause *
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 943719f97f9cd..ce4318a71ee7a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2265,9 +2265,12 @@ class TreeTransform {
///
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide
diff erent behavior.
- OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
- const OMPVarListLocTy &Locs) {
- return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
+ OMPClause *RebuildOMPUseDevicePtrClause(
+ ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
+ OpenMPUseDevicePtrFallbackModifier FallbackModifier,
+ SourceLocation FallbackModifierLoc) {
+ return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
+ VarList, Locs, FallbackModifier, FallbackModifierLoc);
}
/// Build a new OpenMP 'use_device_addr' clause.
@@ -11653,7 +11656,8 @@ OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
Vars.push_back(EVar.get());
}
OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
- return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
+ return getDerived().RebuildOMPUseDevicePtrClause(
+ Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
}
template <typename Derived>
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index b57e4b19f3c57..17801b59963a0 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -12545,6 +12545,8 @@ void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) {
void OMPClauseReader::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
C->setLParenLoc(Record.readSourceLocation());
+ C->setFallbackModifier(Record.readEnum<OpenMPUseDevicePtrFallbackModifier>());
+ C->setFallbackModifierLoc(Record.readSourceLocation());
auto NumVars = C->varlist_size();
auto UniqueDecls = C->getUniqueDeclarationsNum();
auto TotalLists = C->getTotalComponentListNum();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index bab43cbaa2737..2e9f19eb0f51d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8542,6 +8542,8 @@ void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
Record.push_back(C->getTotalComponentListNum());
Record.push_back(C->getTotalComponentsNum());
Record.AddSourceLocation(C->getLParenLoc());
+ Record.writeEnum(C->getFallbackModifier());
+ Record.AddSourceLocation(C->getFallbackModifierLoc());
for (auto *E : C->varlist())
Record.AddStmt(E);
for (auto *VE : C->private_copies())
diff --git a/clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp b/clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp
new file mode 100644
index 0000000000000..060f64f6e86a8
--- /dev/null
+++ b/clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=61 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=61 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=61 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK-LABEL:void f1(int *p, int *q)
+void f1(int *p, int *q) {
+
+// CHECK: #pragma omp target data use_device_ptr(fb_preserve: p)
+#pragma omp target data use_device_ptr(fb_preserve: p)
+ {}
+
+// CHECK: #pragma omp target data use_device_ptr(fb_nullify: p)
+#pragma omp target data use_device_ptr(fb_nullify: p)
+ {}
+
+// Without any fallback modifier
+// CHECK: #pragma omp target data use_device_ptr(p)
+#pragma omp target data use_device_ptr(p)
+ {}
+
+// Multiple variables with fb_preserve
+// CHECK: #pragma omp target data use_device_ptr(fb_preserve: p,q)
+#pragma omp target data use_device_ptr(fb_preserve: p, q)
+ {}
+
+// Multiple variables with fb_nullify
+// CHECK: #pragma omp target data use_device_ptr(fb_nullify: p,q)
+#pragma omp target data use_device_ptr(fb_nullify: p, q)
+ {}
+}
+#endif
diff --git a/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp b/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp
new file mode 100644
index 0000000000000..ae6fda3ce0939
--- /dev/null
+++ b/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=60 -verify=omp60,expected -ferror-limit 200 %s
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=61 -verify=omp61,expected -ferror-limit 200 %s
+
+void f1(int x, int *p, int *q) {
+
+ // Test that fallback modifier is only recognized in OpenMP 6.1+
+#pragma omp target data map(x) use_device_ptr(fb_preserve: p) // omp60-error {{use of undeclared identifier 'fb_preserve'}}
+ {}
+
+#pragma omp target data map(x) use_device_ptr(fb_nullify: p) // omp60-error {{use of undeclared identifier 'fb_nullify'}}
+ {}
+
+ // Without modifier (should work in both versions)
+#pragma omp target data map(x) use_device_ptr(p)
+ {}
+
+ // Unknown modifier: should fail in both versions
+#pragma omp target data map(x) use_device_ptr(fb_abc: p) // expected-error {{use of undeclared identifier 'fb_abc'}}
+ {}
+
+ // Multiple modifiers: should fail in both versions
+#pragma omp target data map(x) use_device_ptr(fb_nullify, fb_preserve: p, q) // omp61-error {{missing ':' after fallback modifier}} omp61-error {{expected expression}} omp61-error {{use of undeclared identifier 'fb_preserve'}} omp60-error {{use of undeclared identifier 'fb_nullify'}} omp60-error {{use of undeclared identifier 'fb_preserve'}}
+ {}
+
+ // Interspersed modifiers/list-items: should fail in both versions
+#pragma omp target data map(x) use_device_ptr(fb_nullify: p, fb_preserve: q) // omp61-error {{use of undeclared identifier 'fb_preserve'}} omp60-error {{use of undeclared identifier 'fb_nullify'}} omp60-error {{use of undeclared identifier 'fb_preserve'}}
+ {}
+
+ // Test missing colon after modifier in OpenMP 6.1 - should error
+#pragma omp target data map(x) use_device_ptr(fb_preserve p) // omp61-error {{missing ':' after fallback modifier}} omp60-error {{use of undeclared identifier 'fb_preserve'}}
+ {}
+}
More information about the cfe-commits
mailing list