forked from OSchip/llvm-project
[flang] Accept sparse argument keyword names for MAX/MIN
Accept any keyword argument names of the form "An" for values of n >= 3 in calls to the intrinsic functions MAX, MIN, and their variants, so long as "n" has no leading zero and all the keywords are distinct. Previously, f18 was needlessly requiring the names to be contiguous. When synthesizing keywords to characterize the procedure's interface, don't conflict with the program's keywords. Differential Revision: https://reviews.llvm.org/D117701
This commit is contained in:
parent
e084679f96
commit
bddfb81a31
|
@ -1183,7 +1183,7 @@ static DynamicType GetBuiltinDerivedType(
|
|||
}
|
||||
|
||||
// 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<parser::CharBlock> keyword,
|
||||
std::set<parser::CharBlock> &set, const char *intrinsicName,
|
||||
parser::ContextualMessages &messages) {
|
||||
|
@ -1191,7 +1191,7 @@ static bool CheckMaxMinArgument(std::optional<parser::CharBlock> keyword,
|
|||
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 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
|
|||
if (const auto &arg{rearranged[j]}) {
|
||||
if (const Expr<SomeType> *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)};
|
||||
|
|
|
@ -5,6 +5,8 @@ real :: x = 0.0 ! prevent folding
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue