[flang-commits] [flang] 2b795ec - [flang] Check for undefined derived types

Peter Steinfeld via flang-commits flang-commits at lists.llvm.org
Fri Jun 4 14:34:11 PDT 2021


Author: Peter Steinfeld
Date: 2021-06-04T14:33:52-07:00
New Revision: 2b795ec682ff4a9afbfe4e5c102a51689b270ecc

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

LOG: [flang] Check for undefined derived types

It's possible to specify refer to an undefined derived type as the type of a
component of another derived type and then never define the type of the
component.  We were not detecting this situation.  To fix this, I
changed the value of isForwardReferenced_ in the symbol's
DerivedTypeDetails and checked for it when performing other derived type
checks.

I also had to record the fact that error messages were previously
emitted for the same problem in some cases so that I could avoid
duplicate messages.

I also added a test.

Differential Revision: https://reviews.llvm.org/D103714

Added: 
    

Modified: 
    flang/include/flang/Semantics/symbol.h
    flang/lib/Semantics/check-declarations.cpp
    flang/lib/Semantics/resolve-names.cpp
    flang/lib/Semantics/type.cpp
    flang/test/Semantics/bad-forward-type.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 293740851125f..b2c53cbb610e2 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -259,7 +259,7 @@ class DerivedTypeDetails {
   void add_paramDecl(const Symbol &symbol) { paramDecls_.push_back(symbol); }
   void add_component(const Symbol &);
   void set_sequence(bool x = true) { sequence_ = x; }
-  void set_isForwardReferenced() { isForwardReferenced_ = true; }
+  void set_isForwardReferenced(bool value) { isForwardReferenced_ = value; }
   const std::list<SourceName> &componentNames() const {
     return componentNames_;
   }

diff  --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 0aaf5fe789c06..56c126b5bc1c8 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -845,6 +845,10 @@ void CheckHelper::CheckSubprogram(
 
 void CheckHelper::CheckDerivedType(
     const Symbol &derivedType, const DerivedTypeDetails &details) {
+  if (details.isForwardReferenced() && !context_.HasError(derivedType)) {
+    messages_.Say("The derived type '%s' has not been defined"_err_en_US,
+        derivedType.name());
+  }
   const Scope *scope{derivedType.scope()};
   if (!scope) {
     CHECK(details.isForwardReferenced());

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5533bdccab50d..3082dc449659d 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3957,6 +3957,7 @@ bool DeclarationVisitor::Pre(const parser::DerivedTypeDef &x) {
   CHECK(scope.symbol());
   CHECK(scope.symbol()->scope() == &scope);
   auto &details{scope.symbol()->get<DerivedTypeDetails>()};
+  details.set_isForwardReferenced(false);
   std::set<SourceName> paramNames;
   for (auto &paramName : std::get<std::list<parser::Name>>(stmt.statement.t)) {
     details.add_paramName(paramName.source);
@@ -5027,7 +5028,7 @@ std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
         Resolve(name, *symbol);
       };
       DerivedTypeDetails details;
-      details.set_isForwardReferenced();
+      details.set_isForwardReferenced(true);
       symbol->set_details(std::move(details));
     } else { // C732
       Say(name, "Derived type '%s' not found"_err_en_US);

diff  --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp
index d2f3aaf55ddec..81a87c3e57dea 100644
--- a/flang/lib/Semantics/type.cpp
+++ b/flang/lib/Semantics/type.cpp
@@ -244,6 +244,7 @@ void DerivedTypeSpec::Instantiate(Scope &containingScope) {
     foldingContext.messages().Say(typeSymbol_.name(),
         "The derived type '%s' was forward-referenced but not defined"_err_en_US,
         typeSymbol_.name());
+    context.SetError(typeSymbol_);
     return;
   }
   EvaluateParameters(context);

diff  --git a/flang/test/Semantics/bad-forward-type.f90 b/flang/test/Semantics/bad-forward-type.f90
index 9177a7c96d15a..71734cd840dff 100644
--- a/flang/test/Semantics/bad-forward-type.f90
+++ b/flang/test/Semantics/bad-forward-type.f90
@@ -90,3 +90,10 @@ subroutine s9
     integer, kind :: n = 3
   end type
 end subroutine s9
+
+subroutine s10
+  type t
+    !ERROR: The derived type 'undef' has not been defined
+    type(undef), pointer :: y
+  end type
+end subroutine s10


        


More information about the flang-commits mailing list