[flang] Fix crashes on calls to non-procedures

When a procedure reference is attempted to an entity that just
isn't a procedure, say so.

Differential Revision: https://reviews.llvm.org/D104329
This commit is contained in:
peter klausler 2021-06-15 15:15:34 -07:00
parent c29555342c
commit e5813a683a
4 changed files with 51 additions and 11 deletions

View File

@ -1827,6 +1827,12 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
if (context_.HasError(sym)) {
return std::nullopt;
}
if (!IsProcedure(*sym)) {
AttachDeclaration(
Say(sc.component.source, "'%s' is not a procedure"_err_en_US,
sc.component.source),
*sym);
}
if (auto *dtExpr{UnwrapExpr<Expr<SomeDerived>>(*base)}) {
if (sym->has<semantics::GenericDetails>()) {
AdjustActuals adjustment{
@ -2091,10 +2097,16 @@ auto ExpressionAnalyzer::GetCalleeAndArguments(const parser::Name &name,
return CalleeAndArguments{
semantics::SymbolRef{*symbol}, std::move(arguments)};
}
} else {
} else if (IsProcedure(*symbol)) {
return CalleeAndArguments{
ProcedureDesignator{*symbol}, std::move(arguments)};
}
if (!context_.HasError(*symbol)) {
AttachDeclaration(
Say(name.source, "'%s' is not a callable procedure"_err_en_US,
name.source),
*symbol);
}
} else if (std::optional<SpecificCall> specificCall{
context_.intrinsics().Probe(
CallCharacteristics{

View File

@ -6164,16 +6164,10 @@ void ResolveNamesVisitor::HandleProcedureName(
symbol = &MakeSymbol(context().globalScope(), name.source, Attrs{});
}
Resolve(name, *symbol);
if (symbol->has<ModuleDetails>()) {
SayWithDecl(name, *symbol,
"Use of '%s' as a procedure conflicts with its declaration"_err_en_US);
return;
}
if (!symbol->attrs().test(Attr::INTRINSIC)) {
if (!CheckImplicitNoneExternal(name.source, *symbol)) {
return;
if (CheckImplicitNoneExternal(name.source, *symbol)) {
MakeExternal(*symbol);
}
MakeExternal(*symbol);
}
ConvertToProcEntity(*symbol);
SetProcFlag(name, *symbol, flag);

View File

@ -0,0 +1,34 @@
! RUN: %S/test_errors.sh %s %t %flang_fc1
! Ensures that things that aren't procedures aren't allowed to be called.
module m
integer :: i
integer, pointer :: ip
type :: t
end type
type :: pdt(k,len)
integer, kind :: k
integer, len :: len
end type
type(pdt(1,2)) :: x
namelist /nml/i
contains
subroutine s(d)
real d
!ERROR: 'm' is not a callable procedure
call m
!ERROR: Cannot call function 'i' like a subroutine
call i
!ERROR: Cannot call function 'ip' like a subroutine
call ip
!ERROR: 't' is not a callable procedure
call t
!ERROR: 'k' is not a procedure
call x%k
!ERROR: 'len' is not a procedure
call x%len
!ERROR: Use of 'nml' as a procedure conflicts with its declaration
call nml
!ERROR: Cannot call function 'd' like a subroutine
call d
end subroutine
end

View File

@ -71,9 +71,9 @@ subroutine s4
block
import, none
integer :: i
!ERROR: Use of 'm' as a procedure conflicts with its declaration
!ERROR: 'm' is not a callable procedure
i = m()
!ERROR: Use of 'm' as a procedure conflicts with its declaration
!ERROR: 'm' is not a callable procedure
call m()
end block
end