[flang-commits] [flang] e3b6b92 - [flang] Emit error when a positional actual argument follows an argument with a keyword
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Mar 27 15:33:58 PDT 2023
Author: Peter Klausler
Date: 2023-03-27T15:24:14-07:00
New Revision: e3b6b9299c9691c7dcde0f80b8af679a50540979
URL: https://github.com/llvm/llvm-project/commit/e3b6b9299c9691c7dcde0f80b8af679a50540979
DIFF: https://github.com/llvm/llvm-project/commit/e3b6b9299c9691c7dcde0f80b8af679a50540979.diff
LOG: [flang] Emit error when a positional actual argument follows an argument with a keyword
A positional (non-keyword) actual argument or alternate return label is not
allowed to follow an actual argument with a keyword.
Differential Revision: https://reviews.llvm.org/D146575
Added:
Modified:
flang/lib/Evaluate/intrinsics.cpp
flang/lib/Semantics/check-call.cpp
flang/test/Evaluate/fold-ishftc.f90
flang/test/Semantics/collectives01.f90
flang/test/Semantics/collectives02.f90
flang/test/Semantics/collectives03.f90
flang/test/Semantics/collectives04.f90
flang/test/Semantics/lcobound.f90
flang/test/Semantics/ucobound.f90
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 7e8285a8a8d15..a27d211420181 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1543,17 +1543,32 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
dummy[dummyArgPatterns - 1].optionality == Optionality::repeats};
std::vector<ActualArgument *> actualForDummy(
isMaxMin ? 0 : dummyArgPatterns, nullptr);
- int missingActualArguments{0};
+ bool anyMissingActualArgument{false};
std::set<parser::CharBlock> maxMinKeywords;
+ bool anyKeyword{false};
+ int which{0};
for (std::optional<ActualArgument> &arg : arguments) {
- if (!arg) {
- ++missingActualArguments;
- } else if (arg->isAlternateReturn()) {
- messages.Say(arg->sourceLocation(),
- "alternate return specifier not acceptable on call to intrinsic '%s'"_err_en_US,
- name);
- return std::nullopt;
- } else if (isMaxMin) {
+ ++which;
+ if (arg) {
+ if (arg->isAlternateReturn()) {
+ messages.Say(arg->sourceLocation(),
+ "alternate return specifier not acceptable on call to intrinsic '%s'"_err_en_US,
+ name);
+ return std::nullopt;
+ }
+ if (arg->keyword()) {
+ anyKeyword = true;
+ } else if (anyKeyword) {
+ messages.Say(arg ? arg->sourceLocation() : std::nullopt,
+ "actual argument #%d without a keyword may not follow an actual argument with a keyword"_err_en_US,
+ which);
+ return std::nullopt;
+ }
+ } else {
+ anyMissingActualArgument = true;
+ continue;
+ }
+ if (isMaxMin) {
if (CheckMaxMinArgument(arg->keyword(), maxMinKeywords, name, messages)) {
actualForDummy.push_back(&*arg);
} else {
@@ -1561,7 +1576,6 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
}
} else {
bool found{false};
- int slot{missingActualArguments};
for (std::size_t j{0}; j < dummyArgPatterns && !found; ++j) {
if (dummy[j].optionality == Optionality::missing) {
continue;
@@ -1584,7 +1598,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
}
}
} else {
- found = !actualForDummy[j] && slot-- == 0;
+ found = !actualForDummy[j] && !anyMissingActualArgument;
}
if (found) {
actualForDummy[j] = &*arg;
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index e4b65fc8adfe4..d398c5ec0d05a 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -873,8 +873,11 @@ static void RearrangeArguments(const characteristics::Procedure &proc,
actuals.size(), proc.dummyArguments.size());
}
std::map<std::string, evaluate::ActualArgument> kwArgs;
+ bool anyKeyword{false};
+ int which{1};
for (auto &x : actuals) {
- if (x && x->keyword()) {
+ if (!x) {
+ } else if (x->keyword()) {
auto emplaced{
kwArgs.try_emplace(x->keyword()->ToString(), std::move(*x))};
if (!emplaced.second) {
@@ -883,7 +886,13 @@ static void RearrangeArguments(const characteristics::Procedure &proc,
*x->keyword());
}
x.reset();
+ anyKeyword = true;
+ } else if (anyKeyword) {
+ messages.Say(x ? x->sourceLocation() : std::nullopt,
+ "Actual argument #%d without a keyword may not follow any actual argument with a keyword"_err_en_US,
+ which);
}
+ ++which;
}
if (!kwArgs.empty()) {
int index{0};
diff --git a/flang/test/Evaluate/fold-ishftc.f90 b/flang/test/Evaluate/fold-ishftc.f90
index 705134823956c..9fca0175a75c4 100644
--- a/flang/test/Evaluate/fold-ishftc.f90
+++ b/flang/test/Evaluate/fold-ishftc.f90
@@ -1,7 +1,7 @@
! RUN: %python %S/test_folding.py %s %flang_fc1
! Tests folding of ISHFTC
module m
- integer, parameter :: shift8s(*) = ishftc(257, shift = [(ict, ict = -8, 8)], 8)
+ integer, parameter :: shift8s(*) = ishftc(257, shift = [(ict, ict = -8, 8)], size=8)
integer, parameter :: expect1(*) = 256 + [1, 2, 4, 8, 16, 32, 64, 128, &
1, 2, 4, 8, 16, 32, 64, 128, 1]
logical, parameter :: test_1 = all(shift8s == expect1)
diff --git a/flang/test/Semantics/collectives01.f90 b/flang/test/Semantics/collectives01.f90
index c87e228508e15..00e2aefb8f603 100644
--- a/flang/test/Semantics/collectives01.f90
+++ b/flang/test/Semantics/collectives01.f90
@@ -135,7 +135,7 @@ program test_co_sum
!ERROR: 'errmsg=' argument has unacceptable rank 1
call co_sum(d, errmsg=character_array)
- !ERROR: too many actual arguments for intrinsic 'co_sum'
+ !ERROR: actual argument #5 without a keyword may not follow an actual argument with a keyword
call co_sum(r, result_image=1, stat=status, errmsg=message, 3.4)
! keyword argument with incorrect name
diff --git a/flang/test/Semantics/collectives02.f90 b/flang/test/Semantics/collectives02.f90
index 96485ce2ebae6..4febeee17ce8d 100644
--- a/flang/test/Semantics/collectives02.f90
+++ b/flang/test/Semantics/collectives02.f90
@@ -120,7 +120,7 @@ program test_co_min
!ERROR: 'errmsg=' argument has unacceptable rank 1
call co_min(d, errmsg=character_array)
- !ERROR: too many actual arguments for intrinsic 'co_min'
+ !ERROR: actual argument #5 without a keyword may not follow an actual argument with a keyword
call co_min(r, result_image=1, stat=status, errmsg=message, 3.4)
!ERROR: unknown keyword argument to intrinsic 'co_min'
diff --git a/flang/test/Semantics/collectives03.f90 b/flang/test/Semantics/collectives03.f90
index e5de68b99bef0..811a7b79bba5f 100644
--- a/flang/test/Semantics/collectives03.f90
+++ b/flang/test/Semantics/collectives03.f90
@@ -120,7 +120,7 @@ program test_co_max
!ERROR: 'errmsg=' argument has unacceptable rank 1
call co_max(d, errmsg=character_array)
- !ERROR: too many actual arguments for intrinsic 'co_max'
+ !ERROR: actual argument #5 without a keyword may not follow an actual argument with a keyword
call co_max(r, result_image=1, stat=status, errmsg=message, 3.4)
!ERROR: unknown keyword argument to intrinsic 'co_max'
diff --git a/flang/test/Semantics/collectives04.f90 b/flang/test/Semantics/collectives04.f90
index 3cd3c3f422d06..bcd1a7ec29789 100644
--- a/flang/test/Semantics/collectives04.f90
+++ b/flang/test/Semantics/collectives04.f90
@@ -126,7 +126,7 @@ program test_co_broadcast
!ERROR: 'errmsg=' argument has unacceptable rank 1
call co_broadcast(d, errmsg=character_array, source_image=1)
- !ERROR: too many actual arguments for intrinsic 'co_broadcast'
+ !ERROR: actual argument #5 without a keyword may not follow an actual argument with a keyword
call co_broadcast(r, source_image=1, stat=status, errmsg=message, 3.4)
!ERROR: unknown keyword argument to intrinsic 'co_broadcast'
diff --git a/flang/test/Semantics/lcobound.f90 b/flang/test/Semantics/lcobound.f90
index 8feb496e1984e..ce2f001ce2ea7 100644
--- a/flang/test/Semantics/lcobound.f90
+++ b/flang/test/Semantics/lcobound.f90
@@ -104,8 +104,11 @@ program lcobound_tests
!ERROR: missing mandatory 'coarray=' argument
n = lcobound(dim=i, kind=c_int32_t)
+ !ERROR: actual argument #2 without a keyword may not follow an actual argument with a keyword
n = lcobound(coarray=scalar_coarray, i)
+ n = lcobound(coarray=scalar_coarray, dim=i)
+
!ERROR: missing mandatory 'coarray=' argument
lcobounds = lcobound()
diff --git a/flang/test/Semantics/ucobound.f90 b/flang/test/Semantics/ucobound.f90
index da9f995f1a97b..f9da11a03a6b0 100644
--- a/flang/test/Semantics/ucobound.f90
+++ b/flang/test/Semantics/ucobound.f90
@@ -104,8 +104,11 @@ program ucobound_tests
!ERROR: missing mandatory 'coarray=' argument
n = ucobound(dim=i, kind=c_int32_t)
+ !ERROR: actual argument #2 without a keyword may not follow an actual argument with a keyword
n = ucobound(coarray=scalar_coarray, i)
+ n = ucobound(coarray=scalar_coarray, dim=i)
+
!ERROR: missing mandatory 'coarray=' argument
ucobounds = ucobound()
More information about the flang-commits
mailing list