[flang-commits] [flang] cdbfb47 - [flang] Fix bug for forward referenced type

Peter Steinfeld via flang-commits flang-commits at lists.llvm.org
Mon Sep 14 15:23:54 PDT 2020


Author: Peter Steinfeld
Date: 2020-09-14T15:15:58-07:00
New Revision: cdbfb47998cd37ab0384ad944fa8e4ba1e1b47d0

URL: https://github.com/llvm/llvm-project/commit/cdbfb47998cd37ab0384ad944fa8e4ba1e1b47d0
DIFF: https://github.com/llvm/llvm-project/commit/cdbfb47998cd37ab0384ad944fa8e4ba1e1b47d0.diff

LOG: [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

Added: 
    

Modified: 
    flang/lib/Semantics/expression.cpp
    flang/test/Semantics/bad-forward-type.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index fcce08db6ef6..5a2a7df9fb98 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -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());

diff  --git a/flang/test/Semantics/bad-forward-type.f90 b/flang/test/Semantics/bad-forward-type.f90
index 2a8cbc0c9b1a..b7857e1f8af4 100644
--- a/flang/test/Semantics/bad-forward-type.f90
+++ b/flang/test/Semantics/bad-forward-type.f90
@@ -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


        


More information about the flang-commits mailing list