[flang-commits] [flang] 3eef2c2 - [flang] Lower TYPE(*) as fir.box<none>

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Tue Oct 4 12:30:20 PDT 2022


Author: Valentin Clement
Date: 2022-10-04T21:30:09+02:00
New Revision: 3eef2c2b1383a5a4ce20f0c92bf7d31537f87705

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

LOG: [flang] Lower TYPE(*) as fir.box<none>

This patch lowers `TYPE(*)` correctly to fir.box<none>.

Reviewed By: jeanPerier

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

Added: 
    

Modified: 
    flang/docs/PolymorphicEntities.md
    flang/include/flang/Optimizer/Dialect/FIRType.h
    flang/include/flang/Semantics/tools.h
    flang/lib/Lower/CallInterface.cpp
    flang/lib/Semantics/tools.cpp
    flang/test/Lower/polymorphic-types.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/PolymorphicEntities.md b/flang/docs/PolymorphicEntities.md
index 362b899016ff1..8993112ddfc3c 100644
--- a/flang/docs/PolymorphicEntities.md
+++ b/flang/docs/PolymorphicEntities.md
@@ -104,8 +104,13 @@ func.func @bar(%x : !fir.class<none>)
 Assumed type is added in Fortran 2018 and it is available only for dummy
 arguments. It's mainly used for interfaces to non-Fortran code and is similar
 to C's `void`.
+An entity that is declared using the `TYPE(*)` type specifier is assumed-type
+and is an unlimited polymorphic entity. It is not declared to have a type, and
+is not considered to have the same declared type as any other entity,
+including another unlimited polymorphic entity. Its dynamic type and type
+parameters are assumed from its effective argument (7.3.2.2 - 3).
 
-Assumed-type is represented as `!fir.type<*>`.
+Assumed-type is represented in FIR as `!fir.box<none>`.
 
 ### SELECT TYPE construct
 

diff  --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 482fec57a5d83..5246071422f7b 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -307,10 +307,19 @@ inline bool BaseBoxType::classof(mlir::Type type) {
   return type.isa<fir::BoxType, fir::ClassType>();
 }
 
-/// Return a fir.box<T> or fir.class<T> if the type is polymorphic.
+/// Return true iff `ty` is none or fir.array<none>.
+inline bool isNoneOrSeqNone(mlir::Type type) {
+  if (auto seqTy = type.dyn_cast<fir::SequenceType>())
+    return seqTy.getEleTy().isa<mlir::NoneType>();
+  return type.isa<mlir::NoneType>();
+}
+
+/// Return a fir.box<T> or fir.class<T> if the type is polymorphic. If the type
+/// is polymorphic and assumed shape return fir.box<T>.
 inline mlir::Type wrapInClassOrBoxType(mlir::Type eleTy,
-                                       bool isPolymorphic = false) {
-  if (isPolymorphic)
+                                       bool isPolymorphic = false,
+                                       bool isAssumedType = false) {
+  if (isPolymorphic && !isAssumedType)
     return fir::ClassType::get(eleTy);
   return fir::BoxType::get(eleTy);
 }

diff  --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index 3f30cab36296c..c4979660b845b 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -183,6 +183,7 @@ std::optional<parser::Message> WhyNotModifiable(SourceName, const SomeExpr &,
     const Scope &, bool vectorSubscriptIsOk = false);
 const Symbol *IsExternalInPureContext(const Symbol &, const Scope &);
 bool HasCoarray(const parser::Expr &);
+bool IsAssumedType(const Symbol &);
 bool IsPolymorphic(const Symbol &);
 bool IsPolymorphicAllocatable(const Symbol &);
 // Return an error if component symbol is not accessible from scope (7.5.4.8(2))

diff  --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index 583a519b8f632..510cb6081ff7d 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -859,8 +859,8 @@ class Fortran::lower::CallInterfaceImpl {
       type = fir::HeapType::get(type);
     if (obj.attrs.test(Attrs::Pointer))
       type = fir::PointerType::get(type);
-    mlir::Type boxType =
-        fir::wrapInClassOrBoxType(type, obj.type.type().IsPolymorphic());
+    mlir::Type boxType = fir::wrapInClassOrBoxType(
+        type, obj.type.type().IsPolymorphic(), obj.type.type().IsAssumedType());
 
     if (obj.attrs.test(Attrs::Allocatable) || obj.attrs.test(Attrs::Pointer)) {
       // Pass as fir.ref<fir.box> or fir.ref<fir.class>
@@ -957,14 +957,16 @@ class Fortran::lower::CallInterfaceImpl {
     const auto *resTypeAndShape{result.GetTypeAndShape()};
     bool resIsPolymorphic =
         resTypeAndShape && resTypeAndShape->type().IsPolymorphic();
+    bool resIsAssumedType =
+        resTypeAndShape && resTypeAndShape->type().IsAssumedType();
     if (!bounds.empty())
       mlirType = fir::SequenceType::get(bounds, mlirType);
     if (result.attrs.test(Attr::Allocatable))
       mlirType = fir::wrapInClassOrBoxType(fir::HeapType::get(mlirType),
-                                           resIsPolymorphic);
+                                           resIsPolymorphic, resIsAssumedType);
     if (result.attrs.test(Attr::Pointer))
       mlirType = fir::wrapInClassOrBoxType(fir::PointerType::get(mlirType),
-                                           resIsPolymorphic);
+                                           resIsPolymorphic, resIsAssumedType);
 
     if (fir::isa_char(mlirType)) {
       // Character scalar results must be passed as arguments in lowering so

diff  --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index f57548016f938..4b57f141a9207 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -1059,6 +1059,13 @@ bool HasCoarray(const parser::Expr &expression) {
   return false;
 }
 
+bool IsAssumedType(const Symbol &symbol) {
+  if (const DeclTypeSpec * type{symbol.GetType()}) {
+    return type->IsAssumedType();
+  }
+  return false;
+}
+
 bool IsPolymorphic(const Symbol &symbol) {
   if (const DeclTypeSpec * type{symbol.GetType()}) {
     return type->IsPolymorphic();

diff  --git a/flang/test/Lower/polymorphic-types.f90 b/flang/test/Lower/polymorphic-types.f90
index 17008d1a49cce..49175ec564f53 100644
--- a/flang/test/Lower/polymorphic-types.f90
+++ b/flang/test/Lower/polymorphic-types.f90
@@ -158,19 +158,17 @@ function ret_unlimited_polymorphic_pointer() result(ret)
 ! Test assumed type argument types
 ! ------------------------------------------------------------------------------
 
-  ! Follow up patch will add a `fir.assumed_type` attribute to the types in the
-  ! two tests below.
   subroutine assumed_type_dummy(a) bind(c)
     type(*) :: a
   end subroutine assumed_type_dummy
 
   ! CHECK-LABEL: func.func @assumed_type_dummy(
-  ! CHECK-SAME: %{{.*}}: !fir.class<none>
+  ! CHECK-SAME: %{{.*}}: !fir.box<none>
 
   subroutine assumed_type_dummy_array(a) bind(c)
     type(*) :: a(:)
   end subroutine assumed_type_dummy_array
 
   ! CHECK-LABEL: func.func @assumed_type_dummy_array(
-  ! CHECK-SAME: %{{.*}}: !fir.class<!fir.array<?xnone>>
+  ! CHECK-SAME: %{{.*}}: !fir.box<!fir.array<?xnone>>
 end module


        


More information about the flang-commits mailing list