diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp --- a/flang/lib/Semantics/compute-offsets.cpp +++ b/flang/lib/Semantics/compute-offsets.cpp @@ -151,16 +151,12 @@ 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 @@ "'%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().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 --- a/flang/test/Semantics/offsets03.f90 +++ b/flang/test/Semantics/offsets03.f90 @@ -37,3 +37,23 @@ 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