[PATCH] D101330: [flang] Handle structure constructors with forward references to PDTs

Pete Steinfeld via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 27 12:55:49 PDT 2021


This revision was automatically updated to reflect the committed changes.
Closed by commit rG8b550af7a9cf: [flang] Handle structure constructors with forward references to PDTs (authored by PeteSteinfeld).

Changed prior to commit:
  https://reviews.llvm.org/D101330?vs=340672&id=340955#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101330/new/

https://reviews.llvm.org/D101330

Files:
  flang/include/flang/Semantics/expression.h
  flang/lib/Semantics/expression.cpp
  flang/test/Semantics/bad-forward-type.f90


Index: flang/test/Semantics/bad-forward-type.f90
===================================================================
--- flang/test/Semantics/bad-forward-type.f90
+++ flang/test/Semantics/bad-forward-type.f90
@@ -79,3 +79,14 @@
     real :: c
   end type
 end subroutine
+
+subroutine s9
+  type con
+    Type(t(3)), pointer :: y
+  end type
+  !ERROR: Cannot construct value for derived type 't' before it is defined
+  Integer :: nn = Size(Transfer(t(3)(666),[0]))
+  type :: t(n)
+    integer, kind :: n = 3
+  end type
+end subroutine s9
Index: flang/lib/Semantics/expression.cpp
===================================================================
--- flang/lib/Semantics/expression.cpp
+++ flang/lib/Semantics/expression.cpp
@@ -1463,7 +1463,16 @@
 MaybeExpr ExpressionAnalyzer::Analyze(
     const parser::StructureConstructor &structure) {
   auto &parsedType{std::get<parser::DerivedTypeSpec>(structure.t)};
-  parser::CharBlock typeName{std::get<parser::Name>(parsedType.t).source};
+  parser::Name structureType{std::get<parser::Name>(parsedType.t)};
+  parser::CharBlock &typeName{structureType.source};
+  if (semantics::Symbol * typeSymbol{structureType.symbol}) {
+    if (typeSymbol->has<semantics::DerivedTypeDetails>()) {
+      semantics::DerivedTypeSpec dtSpec{typeName, typeSymbol->GetUltimate()};
+      if (!CheckIsValidForwardReference(dtSpec)) {
+        return std::nullopt;
+      }
+    }
+  }
   if (!parsedType.derivedTypeSpec) {
     return std::nullopt;
   }
@@ -2182,6 +2191,17 @@
   return AssumedTypePointerOrAllocatableDummy(x);
 }
 
+bool ExpressionAnalyzer::CheckIsValidForwardReference(
+    const semantics::DerivedTypeSpec &dtSpec) {
+  if (dtSpec.IsForwardReferenced()) {
+    Say("Cannot construct value for derived type '%s' "
+        "before it is defined"_err_en_US,
+        dtSpec.name());
+    return false;
+  }
+  return true;
+}
+
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::FunctionReference &funcRef,
     std::optional<parser::StructureConstructor> *structureConstructor) {
   const parser::Call &call{funcRef.v};
@@ -2209,11 +2229,7 @@
         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);
+        if (!CheckIsValidForwardReference(dtSpec)) {
           return std::nullopt;
         }
         const semantics::DeclTypeSpec &type{
Index: flang/include/flang/Semantics/expression.h
===================================================================
--- flang/include/flang/Semantics/expression.h
+++ flang/include/flang/Semantics/expression.h
@@ -382,6 +382,7 @@
   template <typename T> T Fold(T &&expr) {
     return evaluate::Fold(foldingContext_, std::move(expr));
   }
+  bool CheckIsValidForwardReference(const semantics::DerivedTypeSpec &);
 
   semantics::SemanticsContext &context_;
   FoldingContext &foldingContext_{context_.foldingContext()};


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101330.340955.patch
Type: text/x-patch
Size: 3150 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210427/c68f8bbc/attachment.bin>


More information about the llvm-commits mailing list