Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -3532,8 +3532,8 @@ def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group, Flags<[CC1Option]>, MarshallingInfoFlag>; -def pedantic : Flag<["-", "--"], "pedantic">, Group, Flags<[CC1Option]>, - MarshallingInfoFlag>; +def pedantic : Flag<["-", "--"], "pedantic">, Group, Flags<[CC1Option,FlangOption,FC1Option]>, + HelpText<"Warn on language extensions">, MarshallingInfoFlag>; def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">, Flags<[CC1Option]>, MarshallingInfoFlag>; def pipe : Flag<["-", "--"], "pipe">, @@ -3633,7 +3633,7 @@ def static_libstdcxx : Flag<["-"], "static-libstdc++">; def static : Flag<["-", "--"], "static">, Group, Flags<[NoArgumentUnused]>; def std_default_EQ : Joined<["-"], "std-default=">; -def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>, +def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option,FlangOption,FC1Option]>, Group, HelpText<"Language standard to compile for">, ValuesCode<[{ const char *Values = Index: clang/lib/Driver/ToolChains/Flang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Flang.cpp +++ clang/lib/Driver/ToolChains/Flang.cpp @@ -21,18 +21,26 @@ void Flang::AddFortranDialectOptions(const ArgList &Args, ArgStringList &CmdArgs) const { - Args.AddAllArgs( - CmdArgs, {options::OPT_ffixed_form, options::OPT_ffree_form, - options::OPT_ffixed_line_length_EQ, options::OPT_fopenmp, - options::OPT_fopenacc, options::OPT_finput_charset_EQ, - options::OPT_fimplicit_none, options::OPT_fno_implicit_none, - options::OPT_fbackslash, options::OPT_fno_backslash, - options::OPT_flogical_abbreviations, - options::OPT_fno_logical_abbreviations, - options::OPT_fxor_operator, options::OPT_fno_xor_operator, - options::OPT_falternative_parameter_statement, - options::OPT_fdefault_real_8, options::OPT_fdefault_integer_8, - options::OPT_fdefault_double_8, options::OPT_flarge_sizes}); + Args.AddAllArgs(CmdArgs, {options::OPT_ffixed_form, + options::OPT_ffree_form, + options::OPT_ffixed_line_length_EQ, + options::OPT_fopenmp, + options::OPT_fopenacc, + options::OPT_finput_charset_EQ, + options::OPT_fimplicit_none, + options::OPT_fno_implicit_none, + options::OPT_fbackslash, + options::OPT_fno_backslash, + options::OPT_flogical_abbreviations, + options::OPT_fno_logical_abbreviations, + options::OPT_fxor_operator, + options::OPT_fno_xor_operator, + options::OPT_falternative_parameter_statement, + options::OPT_fdefault_real_8, + options::OPT_fdefault_integer_8, + options::OPT_fdefault_double_8, + options::OPT_flarge_sizes, + options::OPT_std_EQ}); } void Flang::AddPreprocessingOptions(const ArgList &Args, @@ -42,7 +50,8 @@ void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { Args.AddAllArgs(CmdArgs, - {options::OPT_module_dir, options::OPT_fdebug_module_writer}); + {options::OPT_module_dir, options::OPT_fdebug_module_writer, + options::OPT_pedantic}); } void Flang::ConstructJob(Compilation &C, const JobAction &JA, Index: flang/include/flang/Frontend/CompilerInvocation.h =================================================================== --- flang/include/flang/Frontend/CompilerInvocation.h +++ flang/include/flang/Frontend/CompilerInvocation.h @@ -74,6 +74,8 @@ // Fortran Dialect options Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_; + bool EnableConformanceChecks_ = false; + public: CompilerInvocation() = default; @@ -111,6 +113,9 @@ llvm::ArrayRef commandLineArgs, clang::DiagnosticsEngine &diags); + // Enables the std=f2018 conformance check + void set_EnableConformanceChecks() { EnableConformanceChecks_ = true; } + /// Useful setters void SetModuleDir(std::string &moduleDir) { moduleDir_ = moduleDir; } Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -368,6 +368,26 @@ res.frontendOpts().features_.Enable( Fortran::common::LanguageFeature::OpenMP); } + + //-fpedantic + if (args.hasArg(clang::driver::options::OPT_pedantic)) { + res.set_EnableConformanceChecks(); + } + // -std=f2018. Current behaviour is same as -fpedantic + // TODO: Set proper options when more fortran standards + // are supported. + if (args.hasArg(clang::driver::options::OPT_std_EQ)) { + auto standard = args.getLastArgValue(clang::driver::options::OPT_std_EQ); + // We only allow f2018 as the given standard + if (standard.equals("f2018")) { + res.set_EnableConformanceChecks(); + } else { + const unsigned diagID = + diags.getCustomDiagID(clang::DiagnosticsEngine::Error, + "Only -std=f2018 is allowed currently."); + diags.Report(diagID); + } + } return; } @@ -508,6 +528,11 @@ if (frontendOptions.instrumentedParse_) fortranOptions.instrumentedParse = true; + + // Set the standard + if (EnableConformanceChecks_) { + fortranOptions.features.WarnOnAllNonstandard(); + } } void CompilerInvocation::setSemanticsOpts( Index: flang/test/Driver/driver-help-hidden.f90 =================================================================== --- flang/test/Driver/driver-help-hidden.f90 +++ flang/test/Driver/driver-help-hidden.f90 @@ -45,6 +45,8 @@ ! CHECK-NEXT: -I Add directory to the end of the list of include search paths ! CHECK-NEXT: -module-dir Put MODULE files in ! CHECK-NEXT: -o Write output to +! CHECK-NEXT: -pedantic Warn on language extensions +! CHECK-NEXT: -std= Language standard to compile for ! CHECK-NEXT: -U Undefine macro ! CHECK-NEXT: --version Print version information ! CHECK-NEXT: -Xflang Pass to the flang compiler Index: flang/test/Driver/driver-help.f90 =================================================================== --- flang/test/Driver/driver-help.f90 +++ flang/test/Driver/driver-help.f90 @@ -45,6 +45,8 @@ ! HELP-NEXT: -I Add directory to the end of the list of include search paths ! HELP-NEXT: -module-dir Put MODULE files in ! HELP-NEXT: -o Write output to +! HELP-NEXT: -pedantic Warn on language extensions +! HELP-NEXT: -std= Language standard to compile for ! HELP-NEXT: -U Undefine macro ! HELP-NEXT: --version Print version information ! HELP-NEXT: -Xflang Pass to the flang compiler @@ -91,6 +93,8 @@ ! HELP-FC1-NEXT: -I Add directory to the end of the list of include search paths ! HELP-FC1-NEXT: -module-dir Put MODULE files in ! HELP-FC1-NEXT: -o Write output to +! HELP-FC1-NEXT: -pedantic Warn on language extensions +! HELP-FC1-NEXT: -std= Language standard to compile for ! HELP-FC1-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only. ! HELP-FC1-NEXT: -U Undefine macro ! HELP-FC1-NEXT: --version Print version information Index: flang/test/Driver/std2018.f90 =================================================================== --- /dev/null +++ flang/test/Driver/std2018.f90 @@ -0,0 +1,34 @@ +! Ensure argument -std=f2018 works as expected. + +!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: %flang_fc1 %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT +! RUN: %flang_fc1 -std=f2018 %s 2>&1 | FileCheck %s --check-prefix=GIVEN +! RUN: %flang_fc1 -pedantic %s 2>&1 | FileCheck %s --check-prefix=GIVEN +! RUN: not %flang_fc1 -std=90 %s 2>&1 | FileCheck %s --check-prefix=WRONG + +!----------------------------------------- +! EXPECTED OUTPUT WITHOUT +!----------------------------------------- +! WITHOUT-NOT: A DO loop should terminate with an END DO or CONTINUE + +!----------------------------------------- +! EXPECTED OUTPUT WITH +!----------------------------------------- +! GIVEN: A DO loop should terminate with an END DO or CONTINUE + +!----------------------------------------- +! EXPECTED OUTPUT WITH WRONG +!----------------------------------------- +! WRONG: Only -std=f2018 is allowed currently. + +subroutine foo2() + do 01 m=1,2 + select case (m) + case default + print*, "default", m + case (1) + print*, "start" +01 end select +end subroutine