diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -1183,7 +1183,7 @@ } // Ensure that the keywords of arguments to MAX/MIN and their variants -// are of the form A123 with no duplicates. +// are of the form A123 with no duplicates or leading zeroes. static bool CheckMaxMinArgument(std::optional keyword, std::set &set, const char *intrinsicName, parser::ContextualMessages &messages) { @@ -1191,7 +1191,7 @@ std::size_t j{1}; for (; j < keyword->size(); ++j) { char ch{(*keyword)[j]}; - if (ch < '0' || ch > '9') { + if (ch < (j == 1 ? '1' : '0') || ch > '9') { break; } } @@ -1808,8 +1808,19 @@ if (const auto &arg{rearranged[j]}) { if (const Expr *expr{arg->UnwrapExpr()}) { std::string kw{d.keyword}; - if (isMaxMin) { - kw = "a"s + std::to_string(j + 1); + if (arg->keyword()) { + kw = arg->keyword()->ToString(); + } else if (isMaxMin) { + for (std::size_t k{j + 1};; ++k) { + kw = "a"s + std::to_string(k); + auto iter{std::find_if(dummyArgs.begin(), dummyArgs.end(), + [&kw](const characteristics::DummyArgument &prev) { + return prev.name == kw; + })}; + if (iter == dummyArgs.end()) { + break; + } + } } auto dc{characteristics::DummyArgument::FromActual( std::move(kw), *expr, context)}; diff --git a/flang/test/Semantics/call23.f90 b/flang/test/Semantics/call23.f90 --- a/flang/test/Semantics/call23.f90 +++ b/flang/test/Semantics/call23.f90 @@ -5,6 +5,8 @@ print *, max(a1=x,a1=1) !ERROR: Keyword argument 'a1=' has already been specified positionally (#1) in this procedure reference print *, max(x,a1=1) -!ERROR: Argument keyword 'a6=' is not recognized for this procedure reference -print *, max(a1=x,a2=0,a3=0,a4=0,a6=0) +print *, max(a1=x,a2=0,a4=0) ! ok +print *, max(x,0,a99=0) ! ok +!ERROR: Argument keyword 'a06=' is not known in call to 'max' +print *, max(a1=x,a2=0,a06=0) end