From 3210ea8eea23eb09be69b19f5e7558c958c32791 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 20 Nov 2024 13:39:51 -0600 Subject: [PATCH 1/2] [flang][OpenMP] Verify that N in -fopenmp-version=N is valid For historical versions that are unsupported, emit a warning and assume the currently default version. For values of N that are not integers or that don't correspond to any OpenMP version (old or newer), emit an error. --- flang/lib/Frontend/CompilerInvocation.cpp | 42 ++++++++++++++++++++--- flang/test/Driver/fopenmp-version.F90 | 25 ++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 flang/test/Driver/fopenmp-version.F90 diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 2603a3f6dc643..230991f0aaa34 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -26,6 +26,7 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/OptionUtils.h" #include "clang/Driver/Options.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Frontend/Debug/Options.h" @@ -44,6 +45,7 @@ #include #include #include +#include using namespace Fortran::frontend; @@ -1140,11 +1142,43 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args, res.getLangOpts().OpenMPVersion = 31; res.getFrontendOpts().features.Enable( Fortran::common::LanguageFeature::OpenMP); - if (int Version = getLastArgIntValue( - args, clang::driver::options::OPT_fopenmp_version_EQ, - res.getLangOpts().OpenMPVersion, diags)) { - res.getLangOpts().OpenMPVersion = Version; + if (auto *arg = + args.getLastArg(clang::driver::options::OPT_fopenmp_version_EQ)) { + llvm::ArrayRef ompVersions = llvm::omp::getOpenMPVersions(); + unsigned oldVersions[] = {11, 20, 25, 30}; + unsigned version = 0; + + auto reportBadVersion = [&](llvm::StringRef value) { + const unsigned diagID = + diags.getCustomDiagID(clang::DiagnosticsEngine::Error, + "'%0' is not a valid OpenMP version in '%1', " + "valid versions are %2"); + std::string buffer; + llvm::raw_string_ostream versions(buffer); + llvm::interleaveComma(ompVersions, versions); + + diags.Report(diagID) << value << arg->getAsString(args) << versions.str(); + }; + + llvm::StringRef value = arg->getValue(); + if (!value.getAsInteger(/*radix=*/10, version)) { + if (llvm::is_contained(ompVersions, version)) { + res.getLangOpts().OpenMPVersion = version; + } else if (llvm::is_contained(oldVersions, version)) { + const unsigned diagID = + diags.getCustomDiagID(clang::DiagnosticsEngine::Warning, + "OpenMP version %0 is no longer supported, " + "assuming version %1"); + std::string assumed = std::to_string(res.getLangOpts().OpenMPVersion); + diags.Report(diagID) << value << assumed; + } else { + reportBadVersion(value); + } + } else { + reportBadVersion(value); + } } + if (args.hasArg(clang::driver::options::OPT_fopenmp_force_usm)) { res.getLangOpts().OpenMPForceUSM = 1; } diff --git a/flang/test/Driver/fopenmp-version.F90 b/flang/test/Driver/fopenmp-version.F90 new file mode 100644 index 0000000000000..c2866561461b7 --- /dev/null +++ b/flang/test/Driver/fopenmp-version.F90 @@ -0,0 +1,25 @@ +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=31 %s | FileCheck --check-prefix=V31 %s +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=40 %s | FileCheck --check-prefix=V40 %s +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=45 %s | FileCheck --check-prefix=V45 %s +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=50 %s | FileCheck --check-prefix=V50 %s +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=51 %s | FileCheck --check-prefix=V51 %s +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=52 %s | FileCheck --check-prefix=V52 %s +!RUN: %flang -dM -E -o - -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix=V60 %s + +!V31: #define _OPENMP 201107 +!V40: #define _OPENMP 201307 +!V45: #define _OPENMP 201511 +!V50: #define _OPENMP 201811 +!V51: #define _OPENMP 202011 +!V52: #define _OPENMP 202111 +!V60: #define _OPENMP 202411 + + +!RUN: %flang -c -fopenmp -fopenmp-version=25 %s 2>&1 | FileCheck --check-prefix=WARN-ASSUMED %s + +!WARN-ASSUMED: warning: OpenMP version 25 is no longer supported, assuming version 31 + + +!RUN: not %flang -c -fopenmp -fopenmp-version=29 %s 2>&1 | FileCheck --check-prefix=ERR-BAD %s + +!ERR-BAD: error: '29' is not a valid OpenMP version in '-fopenmp-version=29', valid versions are 31, 40, 45, 50, 51, 52, 60 From 09b21060853a8695147e86285134bfde312e3fc9 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 25 Jun 2025 11:24:54 -0500 Subject: [PATCH 2/2] format --- flang/lib/Frontend/CompilerInvocation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 230991f0aaa34..07d6814da8671 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1166,9 +1166,9 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args, res.getLangOpts().OpenMPVersion = version; } else if (llvm::is_contained(oldVersions, version)) { const unsigned diagID = - diags.getCustomDiagID(clang::DiagnosticsEngine::Warning, - "OpenMP version %0 is no longer supported, " - "assuming version %1"); + diags.getCustomDiagID(clang::DiagnosticsEngine::Warning, + "OpenMP version %0 is no longer supported, " + "assuming version %1"); std::string assumed = std::to_string(res.getLangOpts().OpenMPVersion); diags.Report(diagID) << value << assumed; } else {