From 191a5e34b0678bdb587d39658beb9432ef97c969 Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Tue, 20 Aug 2019 14:49:37 -0700 Subject: [PATCH] [flang] Fix bug in .mod file for some subprogram attributes Some attributes for subprograms can be in the subprogram prefix but others cannot. For the latter, emit a separate attribute statement to specify them. We were already doing that for PRIVATE but not for OPTIONAL. Those may be the only two attributes this can apply to. Fixes flang-compiler/f18#659. Original-commit: flang-compiler/f18@ae67e087800c5aecb8cb2d2aea16d19b8cc8ccf2 Reviewed-on: https://github.com/flang-compiler/f18/pull/675 Tree-same-pre-rewrite: false --- flang/lib/semantics/mod-file.cc | 17 +++++++++++++---- flang/test/semantics/modfile01.f90 | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index 7dffe82..7845b24 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -274,6 +274,10 @@ void ModFileWriter::PutDerivedType(const Symbol &typeSymbol) { decls_ << "end type\n"; } +// Attributes that may be in a subprogram prefix +static const Attrs subprogramPrefixAttrs{Attr::ELEMENTAL, Attr::IMPURE, + Attr::MODULE, Attr::NON_RECURSIVE, Attr::PURE, Attr::RECURSIVE}; + void ModFileWriter::PutSubprogram(const Symbol &symbol) { auto attrs{symbol.attrs()}; auto &details{symbol.get()}; @@ -283,17 +287,22 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) { bindAttrs.set(Attr::BIND_C, true); attrs.set(Attr::BIND_C, false); } - if (attrs.test(Attr::PRIVATE)) { - PutAttr(decls_, Attr::PRIVATE) << "::"; + Attrs prefixAttrs{subprogramPrefixAttrs}; + prefixAttrs &= attrs; + // emit any non-prefix attributes in an attribute statement + attrs &= ~subprogramPrefixAttrs; + std::stringstream ss; + PutAttrs(ss, attrs); + if (!ss.str().empty()) { + decls_ << ss.str().substr(1) << "::"; PutLower(decls_, symbol) << "\n"; - attrs.set(Attr::PRIVATE, false); } bool isInterface{details.isInterface()}; std::ostream &os{isInterface ? decls_ : contains_}; if (isInterface) { os << "interface\n"; } - PutAttrs(os, attrs, std::nullopt, ""s, " "s); + PutAttrs(os, prefixAttrs, std::nullopt, ""s, " "s); os << (details.isFunction() ? "function " : "subroutine "); PutLower(os, symbol) << '('; int n = 0; diff --git a/flang/test/semantics/modfile01.f90 b/flang/test/semantics/modfile01.f90 index 8de9f1b..4b4be59 100644 --- a/flang/test/semantics/modfile01.f90 +++ b/flang/test/semantics/modfile01.f90 @@ -80,3 +80,29 @@ end ! real(4)::f2 ! end !end + +! Test optional dummy procedure +module m4 +contains + subroutine s(f) + interface + logical recursive function f() + implicit none + end function + end interface + optional f + end +end + +!Expect: m4.mod +!module m4 +!contains +! subroutine s(f) +! optional::f +! interface +! recursive function f() +! logical(4)::f +! end +! end interface +! end +!end -- 2.7.4