diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h index 16924e9bd0c01..ad18d7ed83b1b 100644 --- a/flang/lib/Evaluate/fold-implementation.h +++ b/flang/lib/Evaluate/fold-implementation.h @@ -1063,26 +1063,29 @@ Expr RewriteSpecificMINorMAX( auto &intrinsic{DEREF(std::get_if(&funcRef.proc().u))}; // Rewrite MAX1(args) to INT(MAX(args)) and fold. Same logic for MIN1. // Find result type for max/min based on the arguments. - DynamicType resultType{args[0].value().GetType().value()}; - auto *resultTypeArg{&args[0]}; - for (auto j{args.size() - 1}; j > 0; --j) { - DynamicType type{args[j].value().GetType().value()}; - if (type.category() == resultType.category()) { - if (type.kind() > resultType.kind()) { - resultTypeArg = &args[j]; - resultType = type; - } - } else if (resultType.category() == TypeCategory::Integer) { + std::optional resultType; + ActualArgument *resultTypeArg{nullptr}; + for (auto j{args.size()}; j-- > 0;) { + if (args[j]) { + DynamicType type{args[j]->GetType().value()}; // Handle mixed real/integer arguments: all the previous arguments were // integers and this one is real. The type of the MAX/MIN result will // be the one of the real argument. - resultTypeArg = &args[j]; - resultType = type; + if (!resultType || + (type.category() == resultType->category() && + type.kind() > resultType->kind()) || + resultType->category() == TypeCategory::Integer) { + resultType = type; + resultTypeArg = &*args[j]; + } } } + if (!resultType) { // error recovery + return Expr{std::move(funcRef)}; + } intrinsic.name = intrinsic.name.find("max") != std::string::npos ? "max"s : "min"s; - intrinsic.characteristics.value().functionResult.value().SetType(resultType); + intrinsic.characteristics.value().functionResult.value().SetType(*resultType); auto insertConversion{[&](const auto &x) -> Expr { using TR = ResultType; FunctionRef maxRef{std::move(funcRef.proc()), std::move(args)}; diff --git a/flang/test/Semantics/call23.f90 b/flang/test/Semantics/call23.f90 index 2e33cb092df43..38c860ad3b516 100644 --- 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: Keyword argument 'a1=' has already been specified positionally (#1) in this procedure reference +print *, min1(1.,a1=2.,a2=3.) 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'