[flang-commits] [flang] 245eb0a - [flang] Catch structure constructor in its own type definition (#102241)

via flang-commits flang-commits at lists.llvm.org
Thu Aug 8 11:08:04 PDT 2024


Author: Peter Klausler
Date: 2024-08-08T11:08:00-07:00
New Revision: 245eb0a716a839ebe18bd5d489184bebd352e769

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

LOG: [flang] Catch structure constructor in its own type definition (#102241)

The check for a structure constructor to a forward-referenced derived
type wasn't tripping for constructors in the type definition itself. Set
the forward reference flag unconditionally at the beginning of name
resolution for the type definition.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 0ec96d447c0b9..4f1c53f1bb53f 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3026,8 +3026,7 @@ const Symbol *AssumedTypeDummy<parser::PointerObject>(
 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,
+    Say("Cannot construct value for derived type '%s' before it is defined"_err_en_US,
         dtSpec.name());
     return false;
   }

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 2fe45f9c941d7..b4875d87d172c 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -5507,11 +5507,8 @@ void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
   std::optional<DerivedTypeSpec> extendsType{
       ResolveExtendsType(name, extendsName)};
   DerivedTypeDetails derivedTypeDetails;
-  if (Symbol * typeSymbol{FindInScope(currScope(), name)}; typeSymbol &&
-      typeSymbol->has<DerivedTypeDetails>() &&
-      typeSymbol->get<DerivedTypeDetails>().isForwardReferenced()) {
-    derivedTypeDetails.set_isForwardReferenced(true);
-  }
+  // Catch any premature structure constructors within the definition
+  derivedTypeDetails.set_isForwardReferenced(true);
   auto &symbol{MakeSymbol(name, GetAttrs(), std::move(derivedTypeDetails))};
   symbol.ReplaceName(name.source);
   derivedTypeInfo_.type = &symbol;

diff  --git a/flang/test/Semantics/bad-forward-type.f90 b/flang/test/Semantics/bad-forward-type.f90
index 432d450a15f3f..27c6045b0059f 100644
--- a/flang/test/Semantics/bad-forward-type.f90
+++ b/flang/test/Semantics/bad-forward-type.f90
@@ -76,7 +76,8 @@ subroutine s8
   !ERROR: Cannot construct value for derived type 't2' before it is defined
   parameter(y=t2(12.3))
   type t2
-    real :: c
+    !ERROR: Cannot construct value for derived type 't2' before it is defined
+    real :: c = transfer(t2(),0.)
   end type
 end subroutine
 


        


More information about the flang-commits mailing list