[flang-commits] [flang] 084d8be - [flang] Extend common block size to cover equivalence storage

Jean Perier via flang-commits flang-commits at lists.llvm.org
Thu Sep 2 23:14:35 PDT 2021


Author: Jean Perier
Date: 2021-09-03T08:13:39+02:00
New Revision: 084d8bebd0fcad80b0b2890e427e804ca42431d8

URL: https://github.com/llvm/llvm-project/commit/084d8bebd0fcad80b0b2890e427e804ca42431d8
DIFF: https://github.com/llvm/llvm-project/commit/084d8bebd0fcad80b0b2890e427e804ca42431d8.diff

LOG: [flang] Extend common block size to cover equivalence storage

The size of common block should be extended to cover any storage
sequence that are storage associated with the common block via
equivalences (8.10.2.2 point 1 (2)).

In symbol size and offset computation, the size of the common block
was not always extended to cover storage association. It was only done
if the "base symbol of an equivalence group"(*) appeared in a common block
statement. Correct this to cover all cases where a symbol appearing in a
common block statement is storage associated.

(*) the base symbol of an equivalence group is the symbol whose storage
starts first in a storage association (if several symbols starts first,
the base symbol is the last one visited by the algorithm going through
the equivalence sets).

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

Added: 
    

Modified: 
    flang/lib/Semantics/compute-offsets.cpp
    flang/test/Semantics/offsets03.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp
index a78d3f8418bc..5ebe3e482a6a 100644
--- a/flang/lib/Semantics/compute-offsets.cpp
+++ b/flang/lib/Semantics/compute-offsets.cpp
@@ -151,16 +151,12 @@ void ComputeOffsetsHelper::DoCommonBlock(Symbol &commonBlock) {
   for (auto &object : details.objects()) {
     Symbol &symbol{*object};
     DoSymbol(symbol);
+    auto eqIter{equivalenceBlock_.end()};
     auto iter{dependents_.find(symbol)};
     if (iter == dependents_.end()) {
-      // Get full extent of any EQUIVALENCE block into size of COMMON
-      auto eqIter{equivalenceBlock_.find(symbol)};
+      auto eqIter = equivalenceBlock_.find(symbol);
       if (eqIter != equivalenceBlock_.end()) {
-        SizeAndAlignment &blockInfo{eqIter->second};
-        DoEquivalenceBlockBase(symbol, blockInfo);
-        minSize = std::max(
-            minSize, std::max(offset_, symbol.offset() + blockInfo.size));
-        minAlignment = std::max(minAlignment, blockInfo.alignment);
+        DoEquivalenceBlockBase(symbol, eqIter->second);
       }
     } else {
       SymbolAndOffset &dep{iter->second};
@@ -183,10 +179,19 @@ void ComputeOffsetsHelper::DoCommonBlock(Symbol &commonBlock) {
             "'%s' cannot backward-extend COMMON block /%s/ via EQUIVALENCE with '%s'"_err_en_US,
             symbol.name(), commonBlock.name(), base.name());
       } else {
+        eqIter = equivalenceBlock_.find(base);
         base.get<ObjectEntityDetails>().set_commonBlock(commonBlock);
         base.set_offset(symbol.offset() - dep.offset);
       }
     }
+    // Get full extent of any EQUIVALENCE block into size of COMMON ( see
+    // 8.10.2.2 point 1 (2))
+    if (eqIter != equivalenceBlock_.end()) {
+      SizeAndAlignment &blockInfo{eqIter->second};
+      minSize = std::max(
+          minSize, std::max(offset_, eqIter->first->offset() + blockInfo.size));
+      minAlignment = std::max(minAlignment, blockInfo.alignment);
+    }
   }
   commonBlock.set_size(std::max(minSize, offset_));
   details.set_alignment(std::max(minAlignment, alignment_));

diff  --git a/flang/test/Semantics/offsets03.f90 b/flang/test/Semantics/offsets03.f90
index 1a308217ee9c..67e68f71f5c5 100644
--- a/flang/test/Semantics/offsets03.f90
+++ b/flang/test/Semantics/offsets03.f90
@@ -37,3 +37,23 @@ module md                   !CHECK: Module scope: md size=1 alignment=1
   common /common1/ d3,d2,d1 !CHECK: common1 size=10 offset=0: CommonBlockDetails alignment=4:
   common /common2/ d4       !CHECK: common2 size=2 offset=0: CommonBlockDetails alignment=2:
 end
+
+! Test extension of common block size through equivalence statements.
+module me
+  integer :: i1, j1, l1(10)
+  equivalence(i1, l1)
+  common /common3/ j1, i1   ! CHECK: common3 size=44 offset=0: CommonBlockDetails alignment=4:
+
+  integer :: i2, j2, l2(10)
+  equivalence(i2, l2(2))
+  common /common4/ j2, i2   ! CHECK: common4 size=40 offset=0: CommonBlockDetails alignment=4:
+
+  integer :: i3, j3, l3(10)
+  equivalence(i3, l3)
+  common /common5/ i3, j3   ! CHECK: common5 size=40 offset=0: CommonBlockDetails alignment=4:
+
+  integer :: i4, j4, l4(10), k4(10)
+  equivalence(i4, l4)
+  equivalence(l4(10), k4)
+  common /common6/ i4, j4   ! CHECK: common6 size=76 offset=0: CommonBlockDetails alignment=4:
+end


        


More information about the flang-commits mailing list