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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
