[PATCH] D103714: [flang] Check for undefined derived types

Pete Steinfeld via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 4 13:26:21 PDT 2021


PeteSteinfeld created this revision.
PeteSteinfeld requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

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 added
a field to 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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103714

Files:
  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


Index: flang/test/Semantics/bad-forward-type.f90
===================================================================
--- flang/test/Semantics/bad-forward-type.f90
+++ flang/test/Semantics/bad-forward-type.f90
@@ -90,3 +90,10 @@
     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
Index: flang/lib/Semantics/type.cpp
===================================================================
--- flang/lib/Semantics/type.cpp
+++ flang/lib/Semantics/type.cpp
@@ -244,6 +244,7 @@
     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);
Index: flang/lib/Semantics/resolve-names.cpp
===================================================================
--- flang/lib/Semantics/resolve-names.cpp
+++ flang/lib/Semantics/resolve-names.cpp
@@ -3953,6 +3953,7 @@
   CHECK(scope.symbol());
   CHECK(scope.symbol()->scope() == &scope);
   auto &details{scope.symbol()->get<DerivedTypeDetails>()};
+  details.set_isDefined();
   std::set<SourceName> paramNames;
   for (auto &paramName : std::get<std::list<parser::Name>>(stmt.statement.t)) {
     details.add_paramName(paramName.source);
Index: flang/lib/Semantics/check-declarations.cpp
===================================================================
--- flang/lib/Semantics/check-declarations.cpp
+++ flang/lib/Semantics/check-declarations.cpp
@@ -833,6 +833,10 @@
 
 void CheckHelper::CheckDerivedType(
     const Symbol &derivedType, const DerivedTypeDetails &details) {
+  if (!details.isDefined() && !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());
Index: flang/include/flang/Semantics/symbol.h
===================================================================
--- flang/include/flang/Semantics/symbol.h
+++ flang/include/flang/Semantics/symbol.h
@@ -255,11 +255,13 @@
   std::map<SourceName, SymbolRef> &finals() { return finals_; }
   const std::map<SourceName, SymbolRef> &finals() const { return finals_; }
   bool isForwardReferenced() const { return isForwardReferenced_; }
+  bool isDefined() const { return isDefined_; }
   void add_paramName(const SourceName &name) { paramNames_.push_back(name); }
   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_isDefined() { isDefined_ = true; }
   const std::list<SourceName> &componentNames() const {
     return componentNames_;
   }
@@ -290,6 +292,7 @@
   std::map<SourceName, SymbolRef> finals_; // FINAL :: subr
   bool sequence_{false};
   bool isForwardReferenced_{false};
+  bool isDefined_{false};
   friend llvm::raw_ostream &operator<<(
       llvm::raw_ostream &, const DerivedTypeDetails &);
 };


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103714.349955.patch
Type: text/x-patch
Size: 3256 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210604/40e9438c/attachment.bin>


More information about the llvm-commits mailing list