Skip to content

Commit 82c7d3d

Browse files
jeanPeriervdonaldson
authored andcommitted
[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
1 parent 011a901 commit 82c7d3d

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

flang/lib/Semantics/compute-offsets.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,12 @@ void ComputeOffsetsHelper::DoCommonBlock(Symbol &commonBlock) {
151151
for (auto &object : details.objects()) {
152152
Symbol &symbol{*object};
153153
DoSymbol(symbol);
154+
auto eqIter{equivalenceBlock_.end()};
154155
auto iter{dependents_.find(symbol)};
155156
if (iter == dependents_.end()) {
156-
// Get full extent of any EQUIVALENCE block into size of COMMON
157-
auto eqIter{equivalenceBlock_.find(symbol)};
157+
auto eqIter = equivalenceBlock_.find(symbol);
158158
if (eqIter != equivalenceBlock_.end()) {
159-
SizeAndAlignment &blockInfo{eqIter->second};
160-
DoEquivalenceBlockBase(symbol, blockInfo);
161-
minSize = std::max(
162-
minSize, std::max(offset_, symbol.offset() + blockInfo.size));
163-
minAlignment = std::max(minAlignment, blockInfo.alignment);
159+
DoEquivalenceBlockBase(symbol, eqIter->second);
164160
}
165161
} else {
166162
SymbolAndOffset &dep{iter->second};
@@ -183,10 +179,19 @@ void ComputeOffsetsHelper::DoCommonBlock(Symbol &commonBlock) {
183179
"'%s' cannot backward-extend COMMON block /%s/ via EQUIVALENCE with '%s'"_err_en_US,
184180
symbol.name(), commonBlock.name(), base.name());
185181
} else {
182+
eqIter = equivalenceBlock_.find(base);
186183
base.get<ObjectEntityDetails>().set_commonBlock(commonBlock);
187184
base.set_offset(symbol.offset() - dep.offset);
188185
}
189186
}
187+
// Get full extent of any EQUIVALENCE block into size of COMMON ( see
188+
// 8.10.2.2 point 1 (2))
189+
if (eqIter != equivalenceBlock_.end()) {
190+
SizeAndAlignment &blockInfo{eqIter->second};
191+
minSize = std::max(
192+
minSize, std::max(offset_, eqIter->first->offset() + blockInfo.size));
193+
minAlignment = std::max(minAlignment, blockInfo.alignment);
194+
}
190195
}
191196
commonBlock.set_size(std::max(minSize, offset_));
192197
details.set_alignment(std::max(minAlignment, alignment_));

flang/test/Semantics/offsets03.f90

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,23 @@ module md !CHECK: Module scope: md size=1 alignment=1
3737
common /common1/ d3,d2,d1 !CHECK: common1 size=10 offset=0: CommonBlockDetails alignment=4:
3838
common /common2/ d4 !CHECK: common2 size=2 offset=0: CommonBlockDetails alignment=2:
3939
end
40+
41+
! Test extension of common block size through equivalence statements.
42+
module me
43+
integer :: i1, j1, l1(10)
44+
equivalence(i1, l1)
45+
common /common3/ j1, i1 ! CHECK: common3 size=44 offset=0: CommonBlockDetails alignment=4:
46+
47+
integer :: i2, j2, l2(10)
48+
equivalence(i2, l2(2))
49+
common /common4/ j2, i2 ! CHECK: common4 size=40 offset=0: CommonBlockDetails alignment=4:
50+
51+
integer :: i3, j3, l3(10)
52+
equivalence(i3, l3)
53+
common /common5/ i3, j3 ! CHECK: common5 size=40 offset=0: CommonBlockDetails alignment=4:
54+
55+
integer :: i4, j4, l4(10), k4(10)
56+
equivalence(i4, l4)
57+
equivalence(l4(10), k4)
58+
common /common6/ i4, j4 ! CHECK: common6 size=76 offset=0: CommonBlockDetails alignment=4:
59+
end

0 commit comments

Comments
 (0)