diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -200,6 +200,10 @@ const Symbol &last{ref.GetLastSymbol()}; const Symbol &symbol{BypassGeneric(last).GetUltimate()}; if (semantics::IsProcedure(symbol)) { + if (symbol.attrs().test(semantics::Attr::ABSTRACT)) { + Say("Abstract procedure interface '%s' may not be used as a designator"_err_en_US, + last.name()); + } if (auto *component{std::get_if(&ref.u)}) { return Expr{ProcedureDesignator{std::move(*component)}}; } else if (!std::holds_alternative(ref.u)) { @@ -2340,6 +2344,10 @@ // re-resolve name to the specific procedure name.symbol = const_cast(resolution); } + } else if (IsProcedure(ultimate) && + ultimate.attrs().test(semantics::Attr::ABSTRACT)) { + Say("Abstract procedure interface '%s' may not be referenced"_err_en_US, + name.source); } else { resolution = symbol; } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -6981,10 +6981,7 @@ if (!symbol->has()) { CheckImplicitNoneExternal(name.source, *symbol); } - if (symbol->has() && - symbol->attrs().test(Attr::ABSTRACT)) { - Say(name, "Abstract interface '%s' may not be called"_err_en_US); - } else if (IsProcedure(*symbol) || symbol->has() || + if (IsProcedure(*symbol) || symbol->has() || symbol->has()) { // Symbols with DerivedTypeDetails and AssocEntityDetails are accepted // here as procedure-designators because this means the related diff --git a/flang/test/Semantics/abstract02.f90 b/flang/test/Semantics/abstract02.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/abstract02.f90 @@ -0,0 +1,17 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Test misuse of abstract interfaces +program test + abstract interface + subroutine abstract + end subroutine + end interface + procedure(abstract), pointer :: p + !ERROR: Abstract procedure interface 'abstract' may not be referenced + call abstract + !ERROR: Abstract procedure interface 'abstract' may not be used as a designator + p => abstract + !ERROR: Abstract procedure interface 'abstract' may not be used as a designator + call foo(abstract) + !ERROR: Abstract procedure interface 'abstract' may not be used as a designator + print *, associated(p, abstract) +end diff --git a/flang/test/Semantics/resolve20.f90 b/flang/test/Semantics/resolve20.f90 --- a/flang/test/Semantics/resolve20.f90 +++ b/flang/test/Semantics/resolve20.f90 @@ -3,6 +3,8 @@ abstract interface subroutine foo end subroutine + subroutine foo2 + end subroutine end interface procedure() :: a @@ -70,9 +72,9 @@ subroutine bar end subroutine subroutine test - !ERROR: Abstract interface 'foo' may not be called - call foo() - !ERROR: Abstract interface 'f' may not be called + !ERROR: Abstract procedure interface 'foo2' may not be referenced + call foo2() + !ERROR: Abstract procedure interface 'f' may not be referenced x = f() end subroutine end module