diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4731,6 +4731,9 @@ def flarge_sizes : Flag<["-"],"flarge-sizes">, Group, HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">; +def fnon_arg_intent : Flag<["-"],"fnon-arg-intent">, Group, + HelpText<"Allow use of INTENT attribute not for dummy arguments">; + def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -21,19 +21,27 @@ 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, - options::OPT_fno_automatic}); + 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_fno_automatic, + options::OPT_fnon_arg_intent}); } void Flang::AddPreprocessingOptions(const ArgList &Args, diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h --- a/flang/include/flang/Common/Fortran-features.h +++ b/flang/include/flang/Common/Fortran-features.h @@ -32,7 +32,8 @@ OldLabelDoEndStatements, LogicalIntegerAssignment, EmptySourceFile, ProgramReturn, ImplicitNoneTypeNever, ImplicitNoneTypeAlways, ForwardRefDummyImplicitNone, OpenAccessAppend, BOZAsDefaultInteger, - DistinguishableSpecifics, DefaultSave, PointerInSeqType, NonCharacterFormat) + DistinguishableSpecifics, DefaultSave, PointerInSeqType, NonCharacterFormat, + NonDummyArgumentIntent) using LanguageFeatures = EnumSet; @@ -46,6 +47,7 @@ disable_.set(LanguageFeature::ImplicitNoneTypeNever); disable_.set(LanguageFeature::ImplicitNoneTypeAlways); disable_.set(LanguageFeature::DefaultSave); + disable_.set(LanguageFeature::NonDummyArgumentIntent); // These features, if enabled, conflict with valid standard usage, // so there are disabled here by default. disable_.set(LanguageFeature::BackslashEscapes); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -533,6 +533,12 @@ Fortran::common::LanguageFeature::OpenMP); } + // -fnv-non-arg-intent + if (args.hasArg(clang::driver::options::OPT_fnon_arg_intent)) { + res.frontendOpts().features.Enable( + Fortran::common::LanguageFeature::NonDummyArgumentIntent); + } + // -pedantic if (args.hasArg(clang::driver::options::OPT_pedantic)) { res.set_EnableConformanceChecks(); diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -533,8 +533,10 @@ } else if (symbol.attrs().test(Attr::INTENT_IN) || symbol.attrs().test(Attr::INTENT_OUT) || symbol.attrs().test(Attr::INTENT_INOUT)) { - messages_.Say("INTENT attributes may apply only to a dummy " - "argument"_err_en_US); // C843 + if (!context_.languageFeatures().IsEnabled( + Fortran::common::LanguageFeature::NonDummyArgumentIntent)) + messages_.Say("INTENT attributes may apply only to a dummy " + "argument"_err_en_US); // C843 } else if (IsOptional(symbol)) { messages_.Say("OPTIONAL attribute may apply only to a dummy " "argument"_err_en_US); // C849 @@ -766,8 +768,10 @@ } else if (symbol.attrs().test(Attr::INTENT_IN) || symbol.attrs().test(Attr::INTENT_OUT) || symbol.attrs().test(Attr::INTENT_INOUT)) { - messages_.Say("INTENT attributes may apply only to a dummy " - "argument"_err_en_US); // C843 + if (!context_.languageFeatures().IsEnabled( + Fortran::common::LanguageFeature::NonDummyArgumentIntent)) + messages_.Say("INTENT attributes may apply only to a dummy " + "argument"_err_en_US); // C843 } else if (IsOptional(symbol)) { messages_.Say("OPTIONAL attribute may apply only to a dummy " "argument"_err_en_US); // C849 diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -42,6 +42,7 @@ ! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations ! CHECK-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE ! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics +! CHECK-NEXT: -fnon-arg-intent Allow use of INTENT attribute not for dummy arguments ! CHECK-NEXT: -fopenacc Enable OpenACC ! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -42,6 +42,7 @@ ! HELP-NEXT: -flogical-abbreviations Enable logical abbreviations ! HELP-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE ! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics +! HELP-NEXT: -fnon-arg-intent Allow use of INTENT attribute not for dummy arguments ! HELP-NEXT: -fopenacc Enable OpenACC ! HELP-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! HELP-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. @@ -115,6 +116,7 @@ ! HELP-FC1-NEXT: Do not use the analyzed objects when unparsing ! HELP-FC1-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE ! HELP-FC1-NEXT: -fno-reformat Dump the cooked character stream in -E mode +! HELP-FC1-NEXT: -fnon-arg-intent Allow use of INTENT attribute not for dummy arguments ! HELP-FC1-NEXT: -fopenacc Enable OpenACC ! HELP-FC1-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! HELP-FC1-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90 --- a/flang/test/Driver/frontend-forwarding.f90 +++ b/flang/test/Driver/frontend-forwarding.f90 @@ -7,6 +7,7 @@ ! RUN: -fdefault-integer-8 \ ! RUN: -fdefault-real-8 \ ! RUN: -flarge-sizes \ +! RUN: -fnon-arg-intent \ ! RUN: -mllvm -print-before-all\ ! RUN: -P \ ! RUN: | FileCheck %s @@ -17,4 +18,5 @@ ! CHECK: "-fdefault-integer-8" ! CHECK: "-fdefault-real-8" ! CHECK: "-flarge-sizes" +! CHECK: "-fnon-arg-intent" ! CHECK: "-mllvm" "-print-before-all" diff --git a/flang/test/Semantics/non-arg-intent.f90 b/flang/test/Semantics/non-arg-intent.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/non-arg-intent.f90 @@ -0,0 +1,5 @@ +!RUN: %flang_fc1 %s -fnon-arg-intent +function foo() result(res) + integer, intent(out) :: res + procedure(), intent(in) :: p1 +end function foo \ No newline at end of file