[flang] Fix bug for forward referenced type

A type name in an IMPLICIT declaration that was later used in a PARAMETER
statement caused problems because the default symbol scope had not yet been
initialized.  I avoided dereferencing in the situation where the default scope
was uninitialized and added a test that triggers the problem.

Also, once I corrected the bad dereference, the compiler was putting out
misleading error messages.  The underlying error us due to violating section
7.5.10, paragraph 4, which states:
  A structure constructor shall not appear before the referenced type is
  defined.

I fixed this by testing to see if a type that is used in a structure
constructor is forward referenced.

Differential Revision: https://reviews.llvm.org/D87535
This commit is contained in:
Peter Steinfeld 2020-09-11 11:02:04 -07:00
parent 3ed89b51da
commit cdbfb47998
2 changed files with 12 additions and 6 deletions

View File

@ -1996,11 +1996,18 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::FunctionReference &funcRef,
const auto &designator{std::get<parser::ProcedureDesignator>(call.t)};
if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
semantics::Scope &scope{context_.FindScope(name->source)};
semantics::DerivedTypeSpec dtSpec{
name->source, derivedType.GetUltimate()};
if (dtSpec.IsForwardReferenced()) {
Say(call.source,
"Cannot construct value for derived type '%s' "
"before it is defined"_err_en_US,
name->source);
return std::nullopt;
}
const semantics::DeclTypeSpec &type{
semantics::FindOrInstantiateDerivedType(scope,
semantics::DerivedTypeSpec{
name->source, derivedType.GetUltimate()},
context_)};
semantics::FindOrInstantiateDerivedType(
scope, std::move(dtSpec), context_)};
auto &mutableRef{const_cast<parser::FunctionReference &>(funcRef)};
*structureConstructor =
mutableRef.ConvertToStructureConstructor(type.derivedTypeSpec());

View File

@ -72,9 +72,8 @@ subroutine s7(x)
end subroutine
subroutine s8
!ERROR: Derived type 't2' was used but never defined
!ERROR: The derived type 't2' was forward-referenced but not defined
implicit type(t2)(x)
!ERROR: Cannot construct value for derived type 't2' before it is defined
parameter(y=t2(12.3))
type t2
real :: c