forked from OSchip/llvm-project
[flang] Add one semantic check for implicit interface
As Fortran 2018 C1533, a nonintrinsic elemental procedure shall not be used as an actual argument. The semantic check for implicit iterface is missed. Reviewed By: klausler Differential Revision: https://reviews.llvm.org/D124379
This commit is contained in:
parent
43c146c96d
commit
303ecc42d4
|
@ -24,8 +24,8 @@ namespace characteristics = Fortran::evaluate::characteristics;
|
||||||
|
|
||||||
namespace Fortran::semantics {
|
namespace Fortran::semantics {
|
||||||
|
|
||||||
static void CheckImplicitInterfaceArg(
|
static void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
|
||||||
evaluate::ActualArgument &arg, parser::ContextualMessages &messages) {
|
parser::ContextualMessages &messages, evaluate::FoldingContext &context) {
|
||||||
auto restorer{
|
auto restorer{
|
||||||
messages.SetLocation(arg.sourceLocation().value_or(messages.at()))};
|
messages.SetLocation(arg.sourceLocation().value_or(messages.at()))};
|
||||||
if (auto kw{arg.keyword()}) {
|
if (auto kw{arg.keyword()}) {
|
||||||
|
@ -73,6 +73,18 @@ static void CheckImplicitInterfaceArg(
|
||||||
messages.Say(
|
messages.Say(
|
||||||
"VOLATILE argument requires an explicit interface"_err_en_US);
|
"VOLATILE argument requires an explicit interface"_err_en_US);
|
||||||
}
|
}
|
||||||
|
} else if (auto argChars{characteristics::DummyArgument::FromActual(
|
||||||
|
"actual argument", *expr, context)}) {
|
||||||
|
const auto *argProcDesignator{
|
||||||
|
std::get_if<evaluate::ProcedureDesignator>(&expr->u)};
|
||||||
|
const auto *argProcSymbol{
|
||||||
|
argProcDesignator ? argProcDesignator->GetSymbol() : nullptr};
|
||||||
|
if (argProcSymbol && !argChars->IsTypelessIntrinsicDummy() &&
|
||||||
|
argProcDesignator && argProcDesignator->IsElemental()) { // C1533
|
||||||
|
evaluate::SayWithDeclaration(messages, *argProcSymbol,
|
||||||
|
"Non-intrinsic ELEMENTAL procedure '%s' may not be passed as an actual argument"_err_en_US,
|
||||||
|
argProcSymbol->name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,7 +889,7 @@ void CheckArguments(const characteristics::Procedure &proc,
|
||||||
auto restorer{messages.SetMessages(buffer)};
|
auto restorer{messages.SetMessages(buffer)};
|
||||||
for (auto &actual : actuals) {
|
for (auto &actual : actuals) {
|
||||||
if (actual) {
|
if (actual) {
|
||||||
CheckImplicitInterfaceArg(*actual, messages);
|
CheckImplicitInterfaceArg(*actual, messages, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,15 @@ subroutine s01(elem, subr)
|
||||||
call subr(B"1010")
|
call subr(B"1010")
|
||||||
end subroutine
|
end subroutine
|
||||||
|
|
||||||
|
subroutine s02
|
||||||
|
!ERROR: Non-intrinsic ELEMENTAL procedure 'elem' may not be passed as an actual argument
|
||||||
|
call sub(elem)
|
||||||
|
contains
|
||||||
|
elemental integer function elem()
|
||||||
|
elem = 1
|
||||||
|
end function
|
||||||
|
end
|
||||||
|
|
||||||
module m01
|
module m01
|
||||||
procedure(sin) :: elem01
|
procedure(sin) :: elem01
|
||||||
interface
|
interface
|
||||||
|
@ -73,6 +82,18 @@ module m02
|
||||||
end subroutine
|
end subroutine
|
||||||
end module
|
end module
|
||||||
|
|
||||||
|
module m03
|
||||||
|
contains
|
||||||
|
subroutine test
|
||||||
|
!ERROR: Non-intrinsic ELEMENTAL procedure 'elem' may not be passed as an actual argument
|
||||||
|
call sub(elem)
|
||||||
|
contains
|
||||||
|
elemental integer function elem()
|
||||||
|
elem = 1
|
||||||
|
end function
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
program p03
|
program p03
|
||||||
logical :: l
|
logical :: l
|
||||||
call s1(index)
|
call s1(index)
|
||||||
|
|
Loading…
Reference in New Issue