https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/146933
OpenMP 6.0 introduced alternative spelling for some directives, with the previous spellings still allowed. Warn the user when a new spelling is encountered with OpenMP version set to an older value. >From 5ad103e08e8a06cfc3708ba83601e073a022bb7e Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 2 Jul 2025 12:49:04 -0500 Subject: [PATCH] [clang][OpenMP] Issue a warning when parsing future directive spelling OpenMP 6.0 introduced alternative spelling for some directives, with the previous spellings still being allowed. Warn the user when a new spelling is encountered with OpenMP version set to an older value. --- clang/include/clang/Basic/DiagnosticGroups.td | 4 +- .../clang/Basic/DiagnosticParseKinds.td | 3 + clang/lib/Parse/ParseOpenMP.cpp | 28 ++++++++-- .../test/OpenMP/openmp-6-future-spellings.cpp | 55 +++++++++++++++++++ 4 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 clang/test/OpenMP/openmp-6-future-spellings.cpp diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 36fa3227fd6a6..ace8663b73a4a 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1530,9 +1530,11 @@ def OpenMPPre51Compat : DiagGroup<"pre-openmp-51-compat">; def OpenMP51Ext : DiagGroup<"openmp-51-extensions">; def OpenMPExtensions : DiagGroup<"openmp-extensions">; def OpenMPTargetException : DiagGroup<"openmp-target-exception">; +def OpenMPFuture : DiagGroup<"openmp-future">; def OpenMP : DiagGroup<"openmp", [ SourceUsesOpenMP, OpenMPClauses, OpenMPLoopForm, OpenMPTarget, - OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException + OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException, + OpenMPFuture ]>; // OpenACC warnings. diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6c30da376dafb..87eb2b724b297 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1488,6 +1488,9 @@ def err_omp_multiple_step_or_linear_modifier : Error< "multiple %select{'step size'|'linear modifier'}0 found in linear clause">; def err_omp_deprecate_old_syntax: Error< "old syntax '%0' on '%1' clause was deprecated, use new syntax '%2'">; +def warn_omp_future_directive_spelling: Warning< + "directive spelling '%0' is introduced in a later OpenMP version">, + InGroup<OpenMPFuture>; def warn_pragma_expected_colon_r_paren : Warning< "missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>; def err_omp_unknown_directive : Error< diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 5256d08259b60..cb9eb3304c317 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -56,6 +56,21 @@ class DeclDirectiveListParserHelper final { }; } // namespace +static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P, + SourceLocation Loc, + OpenMPDirectiveKind Kind, + StringRef Name) { + unsigned Version = P.getLangOpts().OpenMP; + auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name); + assert(D == Kind && "Directive kind mismatch"); + // Ignore the case Version > VR.Max: In OpenMP 6.0 all prior spellings + // are explicitly allowed. + if (Version < VR.Min) + P.Diag(Loc, diag::warn_omp_future_directive_spelling) << Name; + + return Kind; +} + static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) { static const DirectiveNameParser DirParser; @@ -65,7 +80,10 @@ static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) { if (Tok.isAnnotation()) return OMPD_unknown; - S = DirParser.consume(S, P.getPreprocessor().getSpelling(Tok)); + std::string Concat = P.getPreprocessor().getSpelling(Tok); + SourceLocation Loc = Tok.getLocation(); + + S = DirParser.consume(S, Concat); if (S == nullptr) return OMPD_unknown; @@ -73,15 +91,17 @@ static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) { OpenMPDirectiveKind DKind = S->Value; Tok = P.getPreprocessor().LookAhead(0); if (!Tok.isAnnotation()) { - S = DirParser.consume(S, P.getPreprocessor().getSpelling(Tok)); + std::string TS = P.getPreprocessor().getSpelling(Tok); + S = DirParser.consume(S, TS); if (S == nullptr) - return DKind; + return checkOpenMPDirectiveName(P, Loc, DKind, Concat); + Concat += ' ' + TS; P.ConsumeToken(); } } assert(S && "Should have exited early"); - return S->Value; + return checkOpenMPDirectiveName(P, Loc, S->Value, Concat); } static DeclarationName parseOpenMPReductionId(Parser &P) { diff --git a/clang/test/OpenMP/openmp-6-future-spellings.cpp b/clang/test/OpenMP/openmp-6-future-spellings.cpp new file mode 100644 index 0000000000000..642ed3502d475 --- /dev/null +++ b/clang/test/OpenMP/openmp-6-future-spellings.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ferror-limit 100 -o - %s + +// expected-warning@+1 {{directive spelling 'begin declare_target' is introduced in a later OpenMP version}} +#pragma omp begin declare_target +void f0(); +// expected-warning@+1 {{directive spelling 'end declare_target' is introduced in a later OpenMP version}} +#pragma omp end declare_target + +// expected-warning@+1 {{directive spelling 'begin declare_variant' is introduced in a later OpenMP version}} +#pragma omp begin declare_variant match(user={condition(true)}) +void f1(); +// expected-warning@+1 {{directive spelling 'end declare_variant' is introduced in a later OpenMP version}} +#pragma omp end declare_variant + +int x; +// expected-warning@+1 {{directive spelling 'declare_target' is introduced in a later OpenMP version}} +#pragma omp declare_target(x) + +struct A { + int x, y; +}; +// expected-warning@+1 {{directive spelling 'declare_mapper' is introduced in a later OpenMP version}} +#pragma omp declare_mapper(mymapper: A a) map(tofrom:a.x, a.y) +A add(A, A); +// expected-warning@+1 {{directive spelling 'declare_reduction' is introduced in a later OpenMP version}} +#pragma omp declare_reduction(+: A: omp_out = add(omp_in, omp_out)) + +// expected-warning@+1 {{directive spelling 'declare_simd' is introduced in a later OpenMP version}} +#pragma omp declare_simd +void f2(); + +void g3(); +// expected-warning@+1 {{directive spelling 'declare_variant' is introduced in a later OpenMP version}} +#pragma omp declare_variant(g3) match(user={condition(true)}) +void f3() {} + +void fred() { + #pragma omp parallel + { + // expected-warning@+1 {{directive spelling 'cancellation_point' is introduced in a later OpenMP version}} + #pragma omp cancellation_point parallel + } + + // expected-warning@+1 {{directive spelling 'target_data' is introduced in a later OpenMP version}} + #pragma omp target_data map(tofrom: x) + {} + + // expected-warning@+1 {{directive spelling 'target_enter_data' is introduced in a later OpenMP version}} + #pragma omp target_enter_data map(to: x) + // expected-warning@+1 {{directive spelling 'target_exit_data' is introduced in a later OpenMP version}} + #pragma omp target_exit_data map(from: x) + // expected-warning@+1 {{directive spelling 'target_update' is introduced in a later OpenMP version}} + #pragma omp target_update from(x) +} + _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits