[flang-commits] [clang] [flang] [flang] Add checks for Fortran 2023 system clock and add f2023/f202Y to valid arguments of -std= (PR #205938)
via flang-commits
flang-commits at lists.llvm.org
Wed Aug 12 10:04:27 PDT 2026
https://github.com/chris-earl updated https://github.com/llvm/llvm-project/pull/205938
>From 8edfde8339e283482fd0605a690639fd4953184a Mon Sep 17 00:00:00 2001
From: Chris Earl <chris.earl at hpe.com>
Date: Wed, 24 Jun 2026 17:44:36 -0500
Subject: [PATCH 1/6] [flang] Remove unused flags and accessor functions
---
.../flang/Frontend/CompilerInvocation.h | 24 -------------------
.../include/flang/Support/Fortran-features.h | 17 ++-----------
flang/lib/Frontend/CompilerInvocation.cpp | 4 ----
flang/lib/Support/Fortran-features.cpp | 4 ----
4 files changed, 2 insertions(+), 47 deletions(-)
diff --git a/flang/include/flang/Frontend/CompilerInvocation.h b/flang/include/flang/Frontend/CompilerInvocation.h
index d294955af780e..6a94ee1bb47eb 100644
--- a/flang/include/flang/Frontend/CompilerInvocation.h
+++ b/flang/include/flang/Frontend/CompilerInvocation.h
@@ -117,10 +117,6 @@ class CompilerInvocation : public CompilerInvocationBase {
// Fortran Error options
size_t maxErrors = 0;
bool warnAsErr = false;
- // Fortran Warning options
- bool enableConformanceChecks = false;
- bool enableUsageChecks = false;
- bool disableWarnings = false;
/// Used in e.g. unparsing to dump the analyzed rather than the original
/// parse-tree objects.
@@ -203,19 +199,8 @@ class CompilerInvocation : public CompilerInvocationBase {
return useAnalyzedObjectsForUnparse;
}
- bool &getEnableConformanceChecks() { return enableConformanceChecks; }
- const bool &getEnableConformanceChecks() const {
- return enableConformanceChecks;
- }
-
const char *getArgv0() { return argv0; }
- bool &getEnableUsageChecks() { return enableUsageChecks; }
- const bool &getEnableUsageChecks() const { return enableUsageChecks; }
-
- bool &getDisableWarnings() { return disableWarnings; }
- const bool &getDisableWarnings() const { return disableWarnings; }
-
Fortran::parser::AnalyzedObjectsAsFortran &getAsFortran() {
return asFortran;
}
@@ -241,15 +226,6 @@ class CompilerInvocation : public CompilerInvocationBase {
clang::DiagnosticsEngine &diags,
const char *argv0 = nullptr);
- // Enables the std=f2018 conformance check
- void setEnableConformanceChecks() { enableConformanceChecks = true; }
-
- // Enables the usage checks
- void setEnableUsageChecks() { enableUsageChecks = true; }
-
- // Disables all Warnings
- void setDisableWarnings() { disableWarnings = true; }
-
/// Useful setters
void setArgv0(const char *dir) { argv0 = dir; }
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index ebc6f495e59ba..b5e46ca7e095e 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -114,23 +114,13 @@ class LanguageFeatureControl {
}
}
void WarnOnAllNonstandard(bool yes = true);
- bool IsWarnOnAllNonstandard() const { return warnAllLanguage_; }
void WarnOnAllUsage(bool yes = true);
- bool IsWarnOnAllUsage() const { return warnAllUsage_; }
- void DisableAllNonstandardWarnings() {
- warnAllLanguage_ = false;
- warnLanguage_.clear();
- }
- void DisableAllUsageWarnings() {
- warnAllUsage_ = false;
- warnUsage_.clear();
- }
+ void DisableAllNonstandardWarnings() { warnLanguage_.clear(); }
+ void DisableAllUsageWarnings() { warnUsage_.clear(); }
void DisableAllWarnings() {
- disableAllWarnings_ = true;
DisableAllNonstandardWarnings();
DisableAllUsageWarnings();
}
- bool AreWarningsDisabled() const { return disableAllWarnings_; }
bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); }
bool ShouldWarn(LanguageFeature f) const { return warnLanguage_.test(f); }
bool ShouldWarn(UsageWarning w) const { return warnUsage_.test(w); }
@@ -190,10 +180,7 @@ class LanguageFeatureControl {
usageWarningCliCanonicalSpelling_;
LanguageFeatures disable_;
LanguageFeatures warnLanguage_;
- bool warnAllLanguage_{false};
UsageWarnings warnUsage_;
- bool warnAllUsage_{false};
- bool disableAllWarnings_{false};
};
} // namespace Fortran::common
#endif // FORTRAN_SUPPORT_FORTRAN_FEATURES_H_
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 0f1ace5d62667..a0ead8e16925f 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1057,8 +1057,6 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
if (args.hasArg(clang::options::OPT_pedantic)) {
features.WarnOnAllNonstandard();
features.WarnOnAllUsage();
- res.setEnableConformanceChecks();
- res.setEnableUsageChecks();
}
// -Werror option
@@ -1097,7 +1095,6 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
// -w
if (args.hasArg(clang::options::OPT_w)) {
features.DisableAllWarnings();
- res.setDisableWarnings();
}
// Default to off for `flang -fc1`.
@@ -1204,7 +1201,6 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
auto standard = args.getLastArgValue(clang::options::OPT_std_EQ);
// We only allow f2018 as the given standard
if (standard == "f2018") {
- res.setEnableConformanceChecks();
res.getFrontendOpts().features.WarnOnAllNonstandard();
} else {
const unsigned diagID =
diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp
index b8d71867da85d..7cb2eeaa3dbe0 100644
--- a/flang/lib/Support/Fortran-features.cpp
+++ b/flang/lib/Support/Fortran-features.cpp
@@ -326,10 +326,8 @@ std::vector<const char *> LanguageFeatureControl::GetNames(
}
void LanguageFeatureControl::WarnOnAllNonstandard(bool yes) {
- warnAllLanguage_ = yes;
warnLanguage_.reset();
if (yes) {
- disableAllWarnings_ = false;
warnLanguage_.flip();
// These three features do not need to be warned about,
// but we do want their feature flags.
@@ -340,10 +338,8 @@ void LanguageFeatureControl::WarnOnAllNonstandard(bool yes) {
}
void LanguageFeatureControl::WarnOnAllUsage(bool yes) {
- warnAllUsage_ = yes;
warnUsage_.reset();
if (yes) {
- disableAllWarnings_ = false;
warnUsage_.flip();
}
}
>From 12509fc3a107b9a7adcf69270bc27071d77ba297 Mon Sep 17 00:00:00 2001
From: Chris Earl <chris.earl at hpe.com>
Date: Wed, 24 Jun 2026 17:58:14 -0500
Subject: [PATCH 2/6] [flang] Add f2023 and f202Y to valid options for -std=
---
flang/include/flang/Support/LangOptions.def | 2 ++
flang/include/flang/Support/LangOptions.h | 7 +++++++
flang/lib/Frontend/CompilerInvocation.cpp | 18 +++++++++++++-----
.../{std2018-wrong.f90 => std20XX-wrong.f90} | 4 ++--
flang/test/Driver/{std2018.f90 => std20XX.f90} | 4 +++-
5 files changed, 27 insertions(+), 8 deletions(-)
rename flang/test/Driver/{std2018-wrong.f90 => std20XX-wrong.f90} (61%)
rename flang/test/Driver/{std2018.f90 => std20XX.f90} (75%)
diff --git a/flang/include/flang/Support/LangOptions.def b/flang/include/flang/Support/LangOptions.def
index 7ae73c6755b57..10532f61036ce 100644
--- a/flang/include/flang/Support/LangOptions.def
+++ b/flang/include/flang/Support/LangOptions.def
@@ -22,6 +22,8 @@ LANGOPT(Name, Bits, Default)
ENUM_LANGOPT(FPContractMode, FPModeKind, 2, FPM_Fast) ///< FP Contract Mode (off/fast)
/// signed integer overflow handling
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 1, SOB_Undefined)
+/// Specify Fortran standard
+ENUM_LANGOPT(FortranStandard, FortranStandardTy, 3, FortranUnspecified)
/// Indicate a build without the standard GPU libraries.
LANGOPT(NoGPULib , 1, false)
diff --git a/flang/include/flang/Support/LangOptions.h b/flang/include/flang/Support/LangOptions.h
index 1dd676e62a9e5..7c320a66f18ea 100644
--- a/flang/include/flang/Support/LangOptions.h
+++ b/flang/include/flang/Support/LangOptions.h
@@ -43,6 +43,13 @@ class LangOptionsBase {
FPM_Fast,
};
+ enum FortranStandardTy {
+ FortranUnspecified, // default
+ Fortran2018,
+ Fortran2023,
+ Fortran202Y,
+ };
+
#define LANGOPT(Name, Bits, Default) unsigned Name : Bits;
#define ENUM_LANGOPT(Name, Type, Bits, Default)
#include "LangOptions.def"
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index a0ead8e16925f..ca7c10e04c2ea 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1194,18 +1194,26 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
Fortran::common::LanguageFeature::OpenACC);
}
- // -std=f2018
- // TODO: Set proper options when more fortran standards
- // are supported.
+ // -std=f20**
if (args.hasArg(clang::options::OPT_std_EQ)) {
auto standard = args.getLastArgValue(clang::options::OPT_std_EQ);
- // We only allow f2018 as the given standard
if (standard == "f2018") {
res.getFrontendOpts().features.WarnOnAllNonstandard();
+ res.getLangOpts().setFortranStandard(
+ Fortran::common::LangOptions::Fortran2018);
+ } else if (standard == "f2023") {
+ res.getFrontendOpts().features.WarnOnAllNonstandard();
+ res.getLangOpts().setFortranStandard(
+ Fortran::common::LangOptions::Fortran2023);
+ } else if (standard == "f202Y") {
+ res.getFrontendOpts().features.WarnOnAllNonstandard();
+ res.getLangOpts().setFortranStandard(
+ Fortran::common::LangOptions::Fortran202Y);
} else {
const unsigned diagID =
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
- "Only -std=f2018 is allowed currently.");
+ "Only 'f2018', 'f2023', or 'f202Y' are "
+ "accepted to -std= currently.");
diags.Report(diagID);
}
}
diff --git a/flang/test/Driver/std2018-wrong.f90 b/flang/test/Driver/std20XX-wrong.f90
similarity index 61%
rename from flang/test/Driver/std2018-wrong.f90
rename to flang/test/Driver/std20XX-wrong.f90
index 93ba153d75f7f..227bf59e45acb 100644
--- a/flang/test/Driver/std2018-wrong.f90
+++ b/flang/test/Driver/std20XX-wrong.f90
@@ -1,8 +1,8 @@
-! Ensure argument -std=f2018 works as expected.
+! Ensure argument -std=f20XX works as expected.
!-----------------------------------------
! FRONTEND FLANG DRIVER (flang -fc1)
!-----------------------------------------
! RUN: not %flang_fc1 -std=90 %s 2>&1 | FileCheck %s --check-prefix=WRONG
-! WRONG: Only -std=f2018 is allowed currently.
+! WRONG: Only 'f2018', 'f2023', or 'f202Y' are accepted to -std= currently.
diff --git a/flang/test/Driver/std2018.f90 b/flang/test/Driver/std20XX.f90
similarity index 75%
rename from flang/test/Driver/std2018.f90
rename to flang/test/Driver/std20XX.f90
index 1727f92127b71..afec991d1e1a6 100644
--- a/flang/test/Driver/std2018.f90
+++ b/flang/test/Driver/std20XX.f90
@@ -1,10 +1,12 @@
-! Ensure argument -std=f2018 works as expected.
+! Ensure argument -std=f20XX works as expected.
!-----------------------------------------
! FRONTEND FLANG DRIVER (flang -fc1)
!-----------------------------------------
! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
! RUN: %flang_fc1 -fsyntax-only -std=f2018 %s 2>&1 | FileCheck %s --check-prefix=GIVEN
+! RUN: %flang_fc1 -fsyntax-only -std=f2023 %s 2>&1 | FileCheck %s --check-prefix=GIVEN
+! RUN: %flang_fc1 -fsyntax-only -std=f202Y %s 2>&1 | FileCheck %s --check-prefix=GIVEN
! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s --check-prefix=GIVEN
! WITHOUT-NOT: A DO loop should terminate with an END DO or CONTINUE
>From dbb0724476f0f6dfcc8e8d3f7905c676a1fc991b Mon Sep 17 00:00:00 2001
From: Chris Earl <chris.earl at hpe.com>
Date: Thu, 25 Jun 2026 16:01:04 -0500
Subject: [PATCH 3/6] [flang] Add checks for F2023 SYSTEM_CLOCK restrictions
Add checks for the restrictions on SYSTEM_CLOCK arguments in Fortran
2023, and issue warnings for violations.
These checks are enabled by default. These warnings are disabled under
two conditions:
- One or more of -fno-system-clock-strict or -fsystem-clock-strict
appears, and -fno-system-clock-strict appears last.
- If -f{no-}system-clock-strict flags do not appear, and if the Fortran
standard is set (via -std=f20XX), the standard is set to f2018.
---
clang/include/clang/Options/FlangOptions.td | 4 +
.../include/flang/Support/Fortran-features.h | 3 +-
flang/lib/Frontend/CompilerInvocation.cpp | 36 +++++
flang/lib/Semantics/check-call.cpp | 57 ++++++++
flang/lib/Support/Fortran-features.cpp | 7 +
flang/test/Semantics/system_clock.f90 | 123 ++++++++++++++++++
6 files changed, 229 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Semantics/system_clock.f90
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 9d163ba0626ba..5a7652fffd0ae 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -318,6 +318,10 @@ def fno_realloc_lhs : Flag<["-"], "fno-realloc-lhs">, Group<f_Group>,
def frealloc_lhs : Flag<["-"], "frealloc-lhs">, Group<f_Group>,
HelpText<"If an allocatable left-hand side of an intrinsic assignment is unallocated or its shape/type does not match the right-hand side, then it is automatically (re)allocated">;
+defm system_clock_strict : OptOutFC1FFlag<"system-clock-strict",
+ "Issue warnings for violations of SYSTEM_CLOCK argument restrictions from Fortran 2023 (default)",
+ "Do not issue warnings for violations of SYSTEM_CLOCK argument restrictions from Fortran 2023">;
+
//===----------------------------------------------------------------------===//
// Coarray Options
//===----------------------------------------------------------------------===//
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index b5e46ca7e095e..3bc0f5418a85c 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -60,7 +60,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
DefaultStructConstructorNullPointer, AssumedRankIoItem,
MultipleProgramUnitsOnSameLine, AllocatedForAssociated,
OpenMPThreadprivateEquivalence, RelaxedCLocChecks, CudaPinned,
- OpenAccDefaultNoneScalarsStrict, OpenACCMultipleNamesInRoutine)
+ OpenAccDefaultNoneScalarsStrict, OpenACCMultipleNamesInRoutine,
+ SystemClockStrict)
// Portability and suspicious usage warnings
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index ca7c10e04c2ea..491c4c5f4c2d5 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1217,6 +1217,42 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
diags.Report(diagID);
}
}
+
+ // -f{no-}system-clock-strict
+ {
+ // Fortran 2023 introduced restrictions to the arguements of SYSTEM_CLOCK.
+ // Since violations of these restrictions can cause unexpected or incorrect
+ // runtime results, violations should be reported to users at compile time
+ // by default. However, since these restrictions are not in Fortran 2018,
+ // these reports should be warnings and not errors. There are two ways to
+ // enable/disable these warnings:
+ // -f{no-}system-clock-strict
+ // -std=f20{18,23}
+ // Rules for enabling/disabling these warnings:
+ // - If one or more of `-f{no-}system-clock-strict` appear, then the last
+ // dictates whether or not the warnings are enabled.
+ // - If no `-f{no-}system-clock-strict` flags appear and Fortran 2018 has
+ // been set as the Fortran standard to follow, that is `-std=f2018` is
+ // the last `std` flag, then the warnings are disabled.
+ // - Otherwise, the warnings are enabled.
+ auto last = args.getLastArg(clang::options::OPT_fsystem_clock_strict,
+ clang::options::OPT_fno_system_clock_strict);
+ if (last) {
+ if (last->getOption().matches(clang::options::OPT_fno_system_clock_strict)) {
+ // If the last of these args is `-fno-system-clock-strict`, disable the
+ // warnings. Otherwise leave the warnings enabled.
+ res.getFrontendOpts().features.EnableWarning(
+ Fortran::common::LanguageFeature::SystemClockStrict, false);
+ }
+ } else if (res.getLangOpts().getFortranStandard() ==
+ Fortran::common::LangOptions::Fortran2018) {
+ // If the Fortran standard is set to `f2018`, disable the warnings.
+ // Otherwise, leave the warnings enabled.
+ res.getFrontendOpts().features.EnableWarning(
+ Fortran::common::LanguageFeature::SystemClockStrict, false);
+ }
+ }
+
// -fcoarray
if (args.hasArg(clang::options::OPT_fcoarray)) {
res.getFrontendOpts().features.Enable(
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index f91b9b1d0b67d..736b901f8535c 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -2038,6 +2038,61 @@ static void CheckFree(evaluate::ActualArguments &arguments,
}
}
+static void CheckSystemClockIntArgsSameKind(
+ evaluate::ActualArguments &arguments,
+ evaluate::FoldingContext &foldingContext) {
+ std::optional<int> commonKind;
+ if (arguments.size() < 2) {
+ return;
+ }
+ for (const auto &arg : arguments) {
+ if (arg) {
+ auto dyType{arg->GetType()};
+ if (dyType && dyType->category() == TypeCategory::Integer) {
+ if (!commonKind) {
+ commonKind = dyType->kind();
+ } else if (*commonKind != dyType->kind()) {
+ foldingContext.Warn(common::LanguageFeature::SystemClockStrict,
+ arg->sourceLocation(),
+ "Integer arguments to SYSTEM_CLOCK should have the same kind. Given %d and %d."_warn_en_US,
+ *commonKind, dyType->kind());
+ }
+ }
+ }
+ }
+}
+
+static void CheckSystemClockMinSize(evaluate::ActualArguments &arguments,
+ evaluate::FoldingContext &foldingContext) {
+ int defaultInt{
+ foldingContext.defaults().GetDefaultKind(TypeCategory::Integer)};
+ for (const auto &arg : arguments) {
+ if (arg) {
+ auto dyType{arg->GetType()};
+ if (dyType && dyType->category() == TypeCategory::Integer &&
+ dyType->kind() < defaultInt) {
+ foldingContext.Warn(common::LanguageFeature::SystemClockStrict,
+ arg->sourceLocation(),
+ "Integer argument to SYSTEM_CLOCK should be an integer with kind >= %d. Given %d."_warn_en_US,
+ defaultInt, dyType->kind());
+ }
+ }
+ }
+}
+
+static void CheckSystemClock(
+ evaluate::ActualArguments &arguments, SemanticsContext &context) {
+ if (context.ShouldWarn(common::LanguageFeature::SystemClockStrict)) {
+ // Fortran 2023 limits integer arguments to SYSTEM_CLOCK to all having the
+ // same kind.
+ CheckSystemClockIntArgsSameKind(arguments, context.foldingContext());
+
+ // Fortran 2023 limits integer arguments to SYSTEM_CLOCK to having kind as
+ // least as large as the default integer.
+ CheckSystemClockMinSize(arguments, context.foldingContext());
+ }
+}
+
// MOVE_ALLOC (F'2023 16.9.147)
static void CheckMove_Alloc(evaluate::ActualArguments &arguments,
parser::ContextualMessages &messages) {
@@ -2339,6 +2394,8 @@ static void CheckSpecificIntrinsic(const characteristics::Procedure &proc,
CheckTransfer(arguments, context, scope);
} else if (intrinsic.name == "free") {
CheckFree(arguments, context.foldingContext().messages());
+ } else if (intrinsic.name == "system_clock") {
+ CheckSystemClock(arguments, context);
}
}
diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp
index 7cb2eeaa3dbe0..651844ec6f869 100644
--- a/flang/lib/Support/Fortran-features.cpp
+++ b/flang/lib/Support/Fortran-features.cpp
@@ -218,6 +218,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
warnUsage_.set(UsageWarning::IoImpliedDoIndexConflict);
warnLanguage_.set(LanguageFeature::OpenMPThreadprivateEquivalence);
warnLanguage_.set(LanguageFeature::OpenACCMultipleNamesInRoutine);
+ warnLanguage_.set(LanguageFeature::SystemClockStrict);
}
std::optional<LanguageControlFlag> LanguageFeatureControl::FindWarning(
@@ -326,6 +327,9 @@ std::vector<const char *> LanguageFeatureControl::GetNames(
}
void LanguageFeatureControl::WarnOnAllNonstandard(bool yes) {
+ // This feature is set independently and is on by default:
+ bool clockStrict = warnLanguage_.test(LanguageFeature::SystemClockStrict);
+
warnLanguage_.reset();
if (yes) {
warnLanguage_.flip();
@@ -335,6 +339,9 @@ void LanguageFeatureControl::WarnOnAllNonstandard(bool yes) {
warnLanguage_.set(LanguageFeature::OpenACC, false);
warnLanguage_.set(LanguageFeature::CUDA, false);
}
+
+ // This feature is set independently and is on by default:
+ warnLanguage_.set(LanguageFeature::SystemClockStrict, clockStrict);
}
void LanguageFeatureControl::WarnOnAllUsage(bool yes) {
diff --git a/flang/test/Semantics/system_clock.f90 b/flang/test/Semantics/system_clock.f90
new file mode 100644
index 0000000000000..04b03c7ed1698
--- /dev/null
+++ b/flang/test/Semantics/system_clock.f90
@@ -0,0 +1,123 @@
+! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang_fc1 -fsyntax-only -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang_fc1 -fsyntax-only -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
+
+! RUN: %flang_fc1 -fsyntax-only -fno-system-clock-strict -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang_fc1 -fsyntax-only -fsystem-clock-strict -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+
+! RUN: %flang_fc1 -fsyntax-only -fdefault-integer-8 %s 2>&1 | FileCheck --check-prefix=STRICT-8 %s
+! RUN: %flang_fc1 -fsyntax-only -fdefault-integer-8 -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang_fc1 -fsyntax-only -std=f2023 %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang_fc1 -fsyntax-only -std=f202Y %s 2>&1 | FileCheck --check-prefix=STRICT %s
+
+! RUN: %flang_fc1 -fsyntax-only -std=f2023 -std=f2018 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 -std=f2023 %s 2>&1 | FileCheck --check-prefix=STRICT %s
+
+! RUN: %flang_fc1 -fsyntax-only -std=f2023 -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang_fc1 -fsyntax-only -fno-system-clock-strict -std=f2023 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang_fc1 -fsyntax-only -fsystem-clock-strict -std=f2018 %s 2>&1 | FileCheck --check-prefix=STRICT %s
+
+! Tests for SYSTEM_CLOCK argument warnings
+
+program test_system_clock
+ implicit none
+
+ integer(8) :: count8, rate8, max8
+ integer(4) :: count4, rate4, max4
+ integer(2) :: count2, rate2, max2
+ integer(1) :: count1, rate1, max1
+ real(8) :: rate_real8
+ real(4) :: rate_real4
+
+ call system_clock()
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate4)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate_real4)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate4, max4)
+
+ call system_clock(count8, rate8, max8)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count=count4)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count_rate=rate4)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count_max=max4)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate_real4, max4)
+
+ call system_clock(count8, rate_real8, max8)
+
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count=count4, count_rate=rate4, count_max=max4)
+
+ !STRICT: Integer arguments to SYSTEM_CLOCK should have the same kind.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate8)
+
+ !STRICT: Integer arguments to SYSTEM_CLOCK should have the same kind.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate8, max4)
+
+ !STRICT: Integer arguments to SYSTEM_CLOCK should have the same kind.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate4, max8)
+
+ !STRICT: Integer arguments to SYSTEM_CLOCK should have the same kind.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count4, rate_real4, max8)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count2)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count2, rate2)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count2, rate_real4)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count2, rate2, max2)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count2, rate_real4, max2)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count1)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count1, rate1)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count1, rate_real4)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count1, rate1, max1)
+
+ !STRICT: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 4.
+ !STRICT-8: Integer argument to SYSTEM_CLOCK should be an integer with kind >= 8.
+ call system_clock(count1, rate_real4, max1)
+end program
>From 17610a058e1e34132fbd1aa2b99cc9f0fbd9e127 Mon Sep 17 00:00:00 2001
From: Chris Earl <chris.earl at hpe.com>
Date: Fri, 26 Jun 2026 16:39:58 -0500
Subject: [PATCH 4/6] [flang] Fix formatting
---
flang/lib/Frontend/CompilerInvocation.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 491c4c5f4c2d5..917865adb781f 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1236,9 +1236,10 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
// the last `std` flag, then the warnings are disabled.
// - Otherwise, the warnings are enabled.
auto last = args.getLastArg(clang::options::OPT_fsystem_clock_strict,
- clang::options::OPT_fno_system_clock_strict);
+ clang::options::OPT_fno_system_clock_strict);
if (last) {
- if (last->getOption().matches(clang::options::OPT_fno_system_clock_strict)) {
+ if (last->getOption().matches(
+ clang::options::OPT_fno_system_clock_strict)) {
// If the last of these args is `-fno-system-clock-strict`, disable the
// warnings. Otherwise leave the warnings enabled.
res.getFrontendOpts().features.EnableWarning(
>From 1c9335bcc18a8e3febf211fa67b87bdfd521ee26 Mon Sep 17 00:00:00 2001
From: Chris Earl <chris.earl at hpe.com>
Date: Tue, 11 Aug 2026 16:40:53 -0500
Subject: [PATCH 5/6] [flang] Fix flags for F2023 SYSTEM_CLOCK restrictions
checks
Change -fsystem-clock-strict and -fno-system-clock-strict to work in the
Flang driver instead of fc1.
---
clang/include/clang/Options/FlangOptions.td | 7 +++--
clang/lib/Driver/ToolChains/Flang.cpp | 2 ++
flang/lib/Frontend/CompilerInvocation.cpp | 29 +++++++++++--------
flang/test/Semantics/system_clock.f90 | 32 ++++++++++-----------
4 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 5a7652fffd0ae..ff9a4111cf3a1 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -318,9 +318,10 @@ def fno_realloc_lhs : Flag<["-"], "fno-realloc-lhs">, Group<f_Group>,
def frealloc_lhs : Flag<["-"], "frealloc-lhs">, Group<f_Group>,
HelpText<"If an allocatable left-hand side of an intrinsic assignment is unallocated or its shape/type does not match the right-hand side, then it is automatically (re)allocated">;
-defm system_clock_strict : OptOutFC1FFlag<"system-clock-strict",
- "Issue warnings for violations of SYSTEM_CLOCK argument restrictions from Fortran 2023 (default)",
- "Do not issue warnings for violations of SYSTEM_CLOCK argument restrictions from Fortran 2023">;
+def fno_system_clock_strict : Flag<["-"], "fno-system-clock-strict">, Group<f_Group>,
+ HelpText<"Do not issue warnings for violations of SYSTEM_CLOCK argument restrictions from Fortran 2023">;
+def fsystem_clock_strict : Flag<["-"], "fsystem-clock-strict">, Group<f_Group>,
+ HelpText<"Issue warnings for violations of SYSTEM_CLOCK argument restrictions from Fortran 2023 (default)">;
//===----------------------------------------------------------------------===//
// Coarray Options
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index ea4df1db38ec8..2fed6039d97ef 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -62,6 +62,8 @@ void Flang::addFortranDialectOptions(const ArgList &Args,
options::OPT_fhermetic_module_files,
options::OPT_frealloc_lhs,
options::OPT_fno_realloc_lhs,
+ options::OPT_fsystem_clock_strict,
+ options::OPT_fno_system_clock_strict,
options::OPT_fsave_main_program,
options::OPT_fd_lines_as_code,
options::OPT_fd_lines_as_comments,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 917865adb781f..361e9a84baf04 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1237,18 +1237,23 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
// - Otherwise, the warnings are enabled.
auto last = args.getLastArg(clang::options::OPT_fsystem_clock_strict,
clang::options::OPT_fno_system_clock_strict);
- if (last) {
- if (last->getOption().matches(
- clang::options::OPT_fno_system_clock_strict)) {
- // If the last of these args is `-fno-system-clock-strict`, disable the
- // warnings. Otherwise leave the warnings enabled.
- res.getFrontendOpts().features.EnableWarning(
- Fortran::common::LanguageFeature::SystemClockStrict, false);
- }
- } else if (res.getLangOpts().getFortranStandard() ==
- Fortran::common::LangOptions::Fortran2018) {
- // If the Fortran standard is set to `f2018`, disable the warnings.
- // Otherwise, leave the warnings enabled.
+
+ // If the last of the system_clock_strict arguments is
+ // `-fno-system-clock-strict`, disable the warnings.
+ const bool last_is_no_strict =
+ last &&
+ last->getOption().matches(
+ clang::options::OPT_fno_system_clock_strict);
+
+ // If there are no system_clock_strict arguments present and the Fortran
+ // standard is set to `f2018`, disable the warnings.
+ const bool no_arg_and_f2018 =
+ !last &&
+ res.getLangOpts().getFortranStandard() ==
+ Fortran::common::LangOptions::Fortran2018;
+
+ // If either condition is met, disable the warnings.
+ if (last_is_no_strict || no_arg_and_f2018) {
res.getFrontendOpts().features.EnableWarning(
Fortran::common::LanguageFeature::SystemClockStrict, false);
}
diff --git a/flang/test/Semantics/system_clock.f90 b/flang/test/Semantics/system_clock.f90
index 04b03c7ed1698..4c28203bd3e4f 100644
--- a/flang/test/Semantics/system_clock.f90
+++ b/flang/test/Semantics/system_clock.f90
@@ -1,24 +1,24 @@
-! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -fno-system-clock-strict -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -fsystem-clock-strict -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -fno-system-clock-strict -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -fsystem-clock-strict -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -fdefault-integer-8 %s 2>&1 | FileCheck --check-prefix=STRICT-8 %s
-! RUN: %flang_fc1 -fsyntax-only -fdefault-integer-8 -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -fdefault-integer-8 %s 2>&1 | FileCheck --check-prefix=STRICT-8 %s
+! RUN: %flang -fdefault-integer-8 -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -std=f2018 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -std=f2023 %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -std=f202Y %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -std=f2018 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -std=f2023 %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -std=f202Y %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -std=f2023 -std=f2018 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -std=f2018 -std=f2023 %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -std=f2023 -std=f2018 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -std=f2018 -std=f2023 %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -std=f2023 -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -fno-system-clock-strict -std=f2023 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
-! RUN: %flang_fc1 -fsyntax-only -std=f2018 -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
-! RUN: %flang_fc1 -fsyntax-only -fsystem-clock-strict -std=f2018 %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -std=f2023 -fno-system-clock-strict %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -fno-system-clock-strict -std=f2023 %s 2>&1 | FileCheck --allow-empty --implicit-check-not="SYSTEM_CLOCK" %s
+! RUN: %flang -std=f2018 -fsystem-clock-strict %s 2>&1 | FileCheck --check-prefix=STRICT %s
+! RUN: %flang -fsystem-clock-strict -std=f2018 %s 2>&1 | FileCheck --check-prefix=STRICT %s
! Tests for SYSTEM_CLOCK argument warnings
>From 42ff13497bb7ff5a1bc0b6fce71044d67b2d4142 Mon Sep 17 00:00:00 2001
From: Chris Earl <chris.earl at hpe.com>
Date: Wed, 12 Aug 2026 12:02:59 -0500
Subject: [PATCH 6/6] [flang] Simplify logic for F2023 SYSTEM_CLOCK restriction
flags
Change logic for `-f{no-}system-clock-strict` to use `hasFlag()`.
---
flang/lib/Frontend/CompilerInvocation.cpp | 29 ++++++-----------------
1 file changed, 7 insertions(+), 22 deletions(-)
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 361e9a84baf04..f0b510d0d72b7 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1235,28 +1235,13 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
// been set as the Fortran standard to follow, that is `-std=f2018` is
// the last `std` flag, then the warnings are disabled.
// - Otherwise, the warnings are enabled.
- auto last = args.getLastArg(clang::options::OPT_fsystem_clock_strict,
- clang::options::OPT_fno_system_clock_strict);
-
- // If the last of the system_clock_strict arguments is
- // `-fno-system-clock-strict`, disable the warnings.
- const bool last_is_no_strict =
- last &&
- last->getOption().matches(
- clang::options::OPT_fno_system_clock_strict);
-
- // If there are no system_clock_strict arguments present and the Fortran
- // standard is set to `f2018`, disable the warnings.
- const bool no_arg_and_f2018 =
- !last &&
- res.getLangOpts().getFortranStandard() ==
- Fortran::common::LangOptions::Fortran2018;
-
- // If either condition is met, disable the warnings.
- if (last_is_no_strict || no_arg_and_f2018) {
- res.getFrontendOpts().features.EnableWarning(
- Fortran::common::LanguageFeature::SystemClockStrict, false);
- }
+ const bool enable_warning =
+ args.hasFlag(clang::options::OPT_fsystem_clock_strict,
+ clang::options::OPT_fno_system_clock_strict,
+ res.getLangOpts().getFortranStandard() !=
+ Fortran::common::LangOptions::Fortran2018);
+ res.getFrontendOpts().features.EnableWarning(
+ Fortran::common::LanguageFeature::SystemClockStrict, enable_warning);
}
// -fcoarray
More information about the flang-commits
mailing list