llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-driver

Author: chris-earl

<details>
<summary>Changes</summary>

Generalize -pedantic to take an optional argument. Accepted values for this 
argument match the Fortran standards: f77, f90, f95, f2003, f2008, f2018, 
f2023, and f202Y.

This commit does not change the behavior of -pedantic (without an argument), 
and -pedantic=f2018 matches the behavior of -pedantic (without an argument).

When passed as an argument to -pedantic, the Fortran standards behave the same 
way as -pedantic (without an argument), except flang will issue extra warnings 
regarding SYSTEM_CLOCK based on the provided argument/standard:
 - f77: There is no intrinsic SYSTEM_CLOCK.
 - f90, f95, f2003, f2008: Integer arguments to SYSTEM_CLOCK must have the same 
kind as the default integer.
 - f2023, f202Y: Integer arguments to SYSTEM_CLOCK must have kind at least 
equal to the default integer, and in a single SYSTEM_CLOCK call all integer 
arguments must have the same kind.

Note: If the above restrictions are violated, a warning is issued for each 
violation, but it does not change what code will successfully compile. For 
example, if code using SYSTEM_CLOCK would compile without -pedantic=f77, it 
will compile with -pedantic=f77 with an extra warning per use of SYSTEM_CLOCK.

This commit also removes some unused flags (enableConformanceChecks, 
enableUsageChecks) and their associated accessor functions.

---

Patch is 40.07 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/196410.diff


12 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticOptions.def (+6) 
- (modified) clang/include/clang/Basic/DiagnosticOptions.h (+14) 
- (modified) clang/include/clang/Options/Options.td (+11-1) 
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+1) 
- (modified) flang/docs/ReleaseNotes.md (+1) 
- (modified) flang/include/flang/Frontend/CompilerInvocation.h (-24) 
- (modified) flang/include/flang/Support/Fortran-features.h (+90-17) 
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+44-8) 
- (modified) flang/lib/Semantics/check-call.cpp (+112) 
- (modified) flang/lib/Support/Fortran-features.cpp (+33-7) 
- (added) flang/test/Driver/pedantic_args.f90 (+38) 
- (added) flang/test/Semantics/system_clock.f90 (+188) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticOptions.def 
b/clang/include/clang/Basic/DiagnosticOptions.def
index 17d518c2b7fdd..fa6a4ff58818c 100644
--- a/clang/include/clang/Basic/DiagnosticOptions.def
+++ b/clang/include/clang/Basic/DiagnosticOptions.def
@@ -101,6 +101,12 @@ VALUE_DIAGOPT(MessageLength, 32, 0)
 
 DIAGOPT(ShowSafeBufferUsageSuggestions, 1, 0)
 
+ENUM_DIAGOPT(FlangPedanticVersion, FlangPedanticVersionTy, 5,
+             FlangPedanticVersionTy::NoPedantic) /// For Flang, set version of
+                                                 /// pedantic, roughly
+                                                 /// corresponding to Fortran
+                                                 /// standards.
+
 #undef DIAGOPT
 #undef ENUM_DIAGOPT
 #undef VALUE_DIAGOPT
diff --git a/clang/include/clang/Basic/DiagnosticOptions.h 
b/clang/include/clang/Basic/DiagnosticOptions.h
index a230022224de5..2547769486ea6 100644
--- a/clang/include/clang/Basic/DiagnosticOptions.h
+++ b/clang/include/clang/Basic/DiagnosticOptions.h
@@ -65,6 +65,20 @@ inline DiagnosticLevelMask operator&(DiagnosticLevelMask LHS,
 
 raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M);
 
+/// Supported versions of Fortran standards for different levels of pedantic
+/// in Flang.
+enum FlangPedanticVersionTy : unsigned {
+  NoPedantic,
+  f77,
+  f90,
+  f95,
+  f2003,
+  f2008,
+  f2018,
+  f2023,
+  f202Y
+};
+
 /// Options for controlling the compiler diagnostics engine.
 class DiagnosticOptions {
   friend bool ParseDiagnosticArgs(DiagnosticOptions &, llvm::opt::ArgList &,
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 5eeabf4c33b76..a36a5128985f8 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -6321,7 +6321,8 @@ def no_canonical_prefixes : Flag<["-"], 
"no-canonical-prefixes">,
   HelpText<"Use relative paths for invoking subcommands">;
 def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, 
Group<clang_ignored_f_Group>;
 def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">;
-def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
+def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>,
+  Visibility<[FlangOption, FC1Option]>;
 def no__dead__strip__inits__and__terms : Flag<["-"], 
"no_dead_strip_inits_and_terms">;
 def nobuiltininc : Flag<["-"], "nobuiltininc">,
   Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
@@ -6403,6 +6404,15 @@ def pedantic_errors : Flag<["-", "--"], 
"pedantic-errors">, Group<pedantic_Group
 def pedantic : Flag<["-", "--"], "pedantic">, Group<pedantic_Group>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
   HelpText<"Warn on language extensions">, 
MarshallingInfoFlag<DiagnosticOpts<"Pedantic">>;
+def pedantic_EQ : Joined<["-", "--"], "pedantic=">, Group<pedantic_Group>,
+  Visibility<[FlangOption, FC1Option]>,
+  HelpText<"Set the Fortran standard to be used for language extensions">,
+  
Values<"f77,f1977,f90,f1990,f95,f1995,f03,f2003,f08,f2008,f18,f2018,f23,f2023,f2Y,f202Y">,
+  NormalizedValuesScope<"clang::FlangPedanticVersionTy">,
+  NormalizedValues<["f77", "f77", "f90", "f90", "f95", "f95", "f2003", "f2003",
+                    "f2008", "f2008", "f2018", "f2018", "f2023", "f2023",
+                    "f202Y", "f202Y"]>,
+  MarshallingInfoEnum<DiagnosticOpts<"FlangPedanticVersion">, "NoPedantic">;
 def p : Flag<["-"], "p">, HelpText<"Enable mcount instrumentation with prof">;
 def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">,
   Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index ce503b74295e4..2217482212428 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -132,6 +132,7 @@ void Flang::addDebugOptions(const llvm::opt::ArgList &Args, 
const JobAction &JA,
   Args.addAllArgs(CmdArgs,
                   {options::OPT_module_dir, options::OPT_fdebug_module_writer,
                    options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
+                   options::OPT_no_pedantic, options::OPT_pedantic_EQ,
                    options::OPT_std_EQ, options::OPT_W_Joined,
                    options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,
                    options::OPT_funderscoring, options::OPT_fno_underscoring,
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 83f53cfb793a4..df563f7bab896 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -37,6 +37,7 @@ page](https://llvm.org/releases/).
 
 - The warning flags with prefixes -Wopen-mp and -Wopen-acc have been 
deprecated in favor of corrected spellings with the respective prefixes 
-Wopenmp and -Wopenacc. Removal of the deprecated options is planned for LLVM 
25 (July 2027).
 
+- The pedantic flag now takes an optional argument, a Fortran standard: f77, 
f90, f95, f2003, f2008, f2018, f2023, and f202Y. The behavior of the pedantic 
flag without an argument remains unchanged. The pedantic flag with an argument 
warns on all of the same things that the pedantic flag without an argument 
warns. Additionally, when passed a standard as an argument, the pedantic flag 
warns about code not conforming to that standard. Currently, the only 
additional warnings are for the different versions of `SYSTEM_CLOCK` in the 
various standards.
 
 ## Windows Support
 
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 af72b71d9d1e6..47b9532bcda85 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -11,6 +11,7 @@
 
 #include "Fortran.h"
 #include "flang/Common/enum-set.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include <string_view>
 #include <vector>
 
@@ -62,6 +63,9 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
     OpenMPThreadprivateEquivalence, RelaxedCLoc)
 
 // Portability and suspicious usage warnings
+// When adding a new UsageWarning, add it to commonWarnings if it should be
+//   enabled by -pedantic. Or if it is specific to a Fortran standard, add it
+//   to the applicable f**Warnings.
 ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
     NonTargetPassedToTarget, PointerToPossibleNoncontiguous,
     ShortCharacterActual, ShortArrayActual, ImplicitInterfaceActual,
@@ -85,7 +89,9 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
     RealConstantWidening, VolatileOrAsynchronousTemporary, UnusedVariable,
     UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy,
     MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure,
-    IgnoredNoReallocateLHS, CLoc)
+    IgnoredNoReallocateLHS, CLoc, SystemClockNotIntrinsic,
+    SystemClockArgsOnlyInteger, SystemClockIntArgsOnlyDefault,
+    SystemClockIntArgsSameKind, SystemClockMinSize)
 
 using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
 using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
@@ -93,6 +99,85 @@ using LanguageFeatureOrWarning = 
std::variant<LanguageFeature, UsageWarning>;
 using LanguageControlFlag =
     std::pair<LanguageFeatureOrWarning, /*shouldEnable=*/bool>;
 
+// Usage Warnings that are not limited to specific Fortran standards
+static inline UsageWarnings commonWarnings = {UsageWarning::Portability,
+    UsageWarning::PointerToUndefinable, UsageWarning::NonTargetPassedToTarget,
+    UsageWarning::PointerToPossibleNoncontiguous,
+    UsageWarning::ShortCharacterActual, UsageWarning::ShortArrayActual,
+    UsageWarning::ImplicitInterfaceActual, 
UsageWarning::PolymorphicTransferArg,
+    UsageWarning::PointerComponentTransferArg,
+    UsageWarning::TransferSizePresence,
+    UsageWarning::F202XAllocatableBreakingChange,
+    UsageWarning::OptionalMustBePresent, UsageWarning::CommonBlockPadding,
+    UsageWarning::LogicalVsCBool, UsageWarning::BindCCharLength,
+    UsageWarning::ProcDummyArgShapes, UsageWarning::ExternalNameConflict,
+    UsageWarning::FoldingException, UsageWarning::FoldingAvoidsRuntimeCrash,
+    UsageWarning::FoldingValueChecks, UsageWarning::FoldingFailure,
+    UsageWarning::FoldingLimit, UsageWarning::Interoperability,
+    UsageWarning::CharacterInteroperability, UsageWarning::Bounds,
+    UsageWarning::Preprocessing, UsageWarning::Scanning,
+    UsageWarning::OpenAccUsage, UsageWarning::ProcPointerCompatibility,
+    UsageWarning::VoidMold, UsageWarning::KnownBadImplicitInterface,
+    UsageWarning::EmptyCase, UsageWarning::CaseOverflow,
+    UsageWarning::CUDAUsage, UsageWarning::IgnoreTKRUsage,
+    UsageWarning::ExternalInterfaceMismatch, UsageWarning::DefinedOperatorArgs,
+    UsageWarning::Final, UsageWarning::ZeroDoStep,
+    UsageWarning::UnusedForallIndex, UsageWarning::OpenMPUsage,
+    UsageWarning::DataLength, UsageWarning::IgnoredDirective,
+    UsageWarning::HomonymousSpecific, UsageWarning::HomonymousResult,
+    UsageWarning::IgnoredIntrinsicFunctionType, 
UsageWarning::PreviousScalarUse,
+    UsageWarning::RedeclaredInaccessibleComponent, 
UsageWarning::ImplicitShared,
+    UsageWarning::IndexVarRedefinition,
+    UsageWarning::IncompatibleImplicitInterfaces,
+    UsageWarning::VectorSubscriptFinalization,
+    UsageWarning::UndefinedFunctionResult, UsageWarning::UselessIomsg,
+    UsageWarning::MismatchingDummyProcedure,
+    UsageWarning::SubscriptedEmptyArray,
+    UsageWarning::UnsignedLiteralTruncation,
+    UsageWarning::CompatibleDeclarationsFromDistinctModules,
+    UsageWarning::ConstantIsContiguous,
+    UsageWarning::NullActualForDefaultIntentAllocatable,
+    UsageWarning::UseAssociationIntoSameNameSubprogram,
+    UsageWarning::HostAssociatedIntentOutInSpecExpr,
+    UsageWarning::NonVolatilePointerToVolatile,
+    UsageWarning::RealConstantWidening,
+    UsageWarning::VolatileOrAsynchronousTemporary, 
UsageWarning::UnusedVariable,
+    UsageWarning::UsedUndefinedVariable, UsageWarning::BadValueInDeadCode,
+    UsageWarning::AssumedTypeSizeDummy, UsageWarning::MisplacedIgnoreTKR,
+    UsageWarning::NamelistParameter, UsageWarning::ImpureFinalInPure,
+    UsageWarning::IgnoredNoReallocateLHS, UsageWarning::CLoc};
+
+// Usage Warnings for f77
+static inline UsageWarnings f77Warnings = {
+    UsageWarning::SystemClockNotIntrinsic};
+
+// Usage Warnings for f90
+static inline UsageWarnings f90Warnings = {
+    UsageWarning::SystemClockArgsOnlyInteger,
+    UsageWarning::SystemClockIntArgsOnlyDefault};
+
+// Usage Warnings for f95
+static inline UsageWarnings f95Warnings = {
+    UsageWarning::SystemClockArgsOnlyInteger,
+    UsageWarning::SystemClockIntArgsOnlyDefault};
+
+// Usage Warnings for f2003
+static inline UsageWarnings f2003Warnings = {};
+
+// Usage Warnings for f2008
+static inline UsageWarnings f2008Warnings = {};
+
+// Usage Warnings for f2018
+static inline UsageWarnings f2018Warnings = {};
+
+// Usage Warnings for f2023
+static inline UsageWarnings f2023Warnings = {
+    UsageWarning::SystemClockIntArgsSameKind, 
UsageWarning::SystemClockMinSize};
+
+// Usage Warnings for f202Y
+static inline UsageWarnings f202YWarnings = {
+    UsageWarning::SystemClockIntArgsSameKind, 
UsageWarning::SystemClockMinSize};
+
 class LanguageFeatureControl {
 public:
   LanguageFeatureControl();
@@ -113,23 +198,14 @@ 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 WarnOnAllUsage(clang::FlangPedanticVersionTy version =
+                          clang::FlangPedanticVersionTy::f2018);
+  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); }
@@ -189,10 +265,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 e7f4762e167fb..68e12151f3fb9 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -1040,12 +1040,50 @@ static bool parseDiagArgs(CompilerInvocation &res, 
llvm::opt::ArgList &args,
   // The order of these flags (-pedantic -W<feature> -w) is important and is
   // chosen to match clang's behavior.
 
-  // -pedantic
-  if (args.hasArg(clang::options::OPT_pedantic)) {
-    features.WarnOnAllNonstandard();
-    features.WarnOnAllUsage();
-    res.setEnableConformanceChecks();
-    res.setEnableUsageChecks();
+  // -pedantic, -no-pedantic, and -pedantic=f**
+  llvm::opt::Arg *arg = args.getLastArg(clang::options::OPT_pedantic,
+                                        clang::options::OPT_no_pedantic,
+                                        clang::options::OPT_pedantic_EQ);
+  // Pedantic is turned off if there is no pedantic argument or if
+  // -no_pedantic is the last argument.
+  if (arg && !arg->getOption().matches(clang::options::OPT_no_pedantic)) {
+    using FlangPedanticVersionTy = clang::FlangPedanticVersionTy;
+    FlangPedanticVersionTy version = FlangPedanticVersionTy::NoPedantic;
+    if (arg->getOption().matches(clang::options::OPT_pedantic)) {
+      version = FlangPedanticVersionTy::f2018;
+    } else if (arg->getOption().matches(clang::options::OPT_pedantic_EQ)) {
+      std::optional<FlangPedanticVersionTy> val =
+          llvm::StringSwitch<std::optional<FlangPedanticVersionTy>>(
+              arg->getValue())
+              .Case("f77", FlangPedanticVersionTy::f77)
+              .Case("f1977", FlangPedanticVersionTy::f77)
+              .Case("f90", FlangPedanticVersionTy::f90)
+              .Case("f1990", FlangPedanticVersionTy::f90)
+              .Case("f95", FlangPedanticVersionTy::f95)
+              .Case("f1995", FlangPedanticVersionTy::f95)
+              .Case("f2003", FlangPedanticVersionTy::f2003)
+              .Case("f03", FlangPedanticVersionTy::f2003)
+              .Case("f2008", FlangPedanticVersionTy::f2008)
+              .Case("f08", FlangPedanticVersionTy::f2008)
+              .Case("f2018", FlangPedanticVersionTy::f2018)
+              .Case("f18", FlangPedanticVersionTy::f2018)
+              .Case("f2023", FlangPedanticVersionTy::f2023)
+              .Case("f23", FlangPedanticVersionTy::f2023)
+              .Case("f202Y", FlangPedanticVersionTy::f202Y)
+              .Case("f2Y", FlangPedanticVersionTy::f202Y)
+              .Default(std::nullopt);
+      if (!val.has_value()) {
+        diags.Report(clang::diag::err_drv_invalid_value)
+            << arg->getAsString(args) << arg->getValue();
+      } else {
+        version = val.value();
+      }
+    }
+
+    if (version != FlangPedanticVersionTy::NoPedantic) {
+      features.WarnOnAllNonstandard();
+      features.WarnOnAllUsage(version);
+    }
   }
 
   // -Werror option
@@ -1084,7 +1122,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`.
@@ -1193,7 +1230,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/Semantics/check-call.cpp 
b/flang/lib/Semantics/check-call.cpp
index da8880482d4dc..7f35c289b41b6 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -2024,6 +2024,116 @@ static void CheckFree(evaluate::ActualArguments 
&arguments,
   }
 }
 
+static void CheckSystemClockArgsOnlyInteger(
+    evaluate::ActualArguments &arguments,
+    evaluate::FoldingContext &foldingContext) {
+  for (const auto &arg : arguments) {
+    if (arg) {
+      auto dyType{arg->GetType()};
+      if (dyType && dyType->category() != TypeCategory::Integer) {
+        foldingContext.Warn(common::UsageWarning::SystemClockArgsOnlyInteger,
+            arg->sourceLocation(),
+            "Argument to SYSTEM_CLOCK should be integer. Given %s."_warn_en_US,
+            dyType->AsFortran());
+      }
+    }
+  }
+}
+
+static void CheckSystemClockIntArgsOnlyDefault(
+    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::UsageWarning::SystemClockIntArgsOnlyDefault,
+            arg->sourceLocation(),
+            "Integer argument to SYSTEM_CLOCK should be an integer with kind 
== %d. Given %d."_warn_en_US,
+            defaultInt, dyType->kind());
+      }
+    }
+  }
+}
+
+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::I...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/196410
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to