Skip to content

[flang][OpenMP] Verify that N in -fopenmp-version=N is valid #145725

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

kparzysz
Copy link
Contributor

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.

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.
@kparzysz kparzysz requested review from skatrak and tblah June 25, 2025 15:47
@llvmbot llvmbot added flang:driver flang Flang issues not falling into any other category labels Jun 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 25, 2025

@llvm/pr-subscribers-flang-driver

Author: Krzysztof Parzyszek (kparzysz)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/145725.diff

2 Files Affected:

  • (modified) flang/lib/Frontend/CompilerInvocation.cpp (+38-4)
  • (added) flang/test/Driver/fopenmp-version.F90 (+25)
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 <cstdlib>
 #include <memory>
 #include <optional>
+#include <sstream>
 
 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<unsigned> 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

Copy link

github-actions bot commented Jun 25, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#144915 processes the version in the compiler driver not the frontend driver. I chose to do it there for consistency with the old experimental warning.

Would you prefer I move that warning to the frontend driver or do you think we should move these checks to the compiler driver?

@kparzysz
Copy link
Contributor Author

I put it here because this is where the OpenMP version is set.

I guess it would make sense to emit the "incomplete" warning after these checks---you wouldn't have to parse the option, just get the version from the lang options.

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kparzysz kparzysz merged commit b4f4af7 into llvm:main Jun 25, 2025
7 checks passed
@kparzysz kparzysz deleted the users/kparzysz/diagnose-incorrect-versions branch June 25, 2025 16:54
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
…5725)

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:driver flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants