Skip to content

Commit 10a9ec8

Browse files
authored
[flang] Fix crash in structure constructor lowering (llvm#160769)
MLIR types created by lowering for structure constructors appear to be sensitive to the ordering of their components in the typed expression representation used for structure constructors and derived type constant values. At present, the components appear in source position order. When some ancestral types are defined in modules, this ordering can cause their components to be ordered after components defined in extended derived types. This can lead to crashes from incompatible MLIR types. To avoid this issue, sort structure constructor components first in ascending order of derived type extension depth; retain source position ordering for components in the same derived type and for error recovery situations. Fixes llvm#143740.
1 parent 2c58d19 commit 10a9ec8

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

flang/lib/Evaluate/constant.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,45 @@ std::size_t Constant<SomeDerived>::CopyFrom(const Constant<SomeDerived> &source,
389389
return Base::CopyFrom(source, count, resultSubscripts, dimOrder);
390390
}
391391

392+
static std::optional<int> DerivedTypeDepth(const semantics::Scope &scope) {
393+
if (scope.IsDerivedType()) {
394+
for (auto iter{scope.cbegin()}; iter != scope.cend(); ++iter) {
395+
const Symbol &symbol{*iter->second};
396+
if (symbol.test(Symbol::Flag::ParentComp)) {
397+
if (const semantics::DeclTypeSpec *type{symbol.GetType()}) {
398+
if (const semantics::DerivedTypeSpec *derived{type->AsDerived()}) {
399+
const semantics::Scope *parent{derived->scope()};
400+
if (!parent) {
401+
parent = derived->typeSymbol().scope();
402+
}
403+
if (parent) {
404+
if (auto parentDepth{DerivedTypeDepth(*parent)}) {
405+
return 1 + *parentDepth;
406+
}
407+
}
408+
}
409+
}
410+
return std::nullopt; // error recovery
411+
}
412+
}
413+
return 0;
414+
} else {
415+
return std::nullopt; // error recovery
416+
}
417+
}
418+
392419
bool ComponentCompare::operator()(SymbolRef x, SymbolRef y) const {
420+
if (&x->owner() != &y->owner()) {
421+
// Not components of the same derived type; put ancestors' components first.
422+
if (auto xDepth{DerivedTypeDepth(x->owner())}) {
423+
if (auto yDepth{DerivedTypeDepth(y->owner())}) {
424+
if (*xDepth != *yDepth) {
425+
return *xDepth < *yDepth;
426+
}
427+
}
428+
}
429+
}
430+
// Same derived type, distinct instantiations, or error recovery.
393431
return semantics::SymbolSourcePositionCompare{}(x, y);
394432
}
395433

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
!mod$ v1 sum:64657f78d85da21d
2+
module comporder1
3+
type::base
4+
integer(4)::c1
5+
end type
6+
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
!mod$ v1 sum:3235f4a02cdad423
2+
!need$ 64657f78d85da21d n comporder1
3+
module comporder2
4+
use comporder1,only:base
5+
type,extends(base)::intermediate
6+
integer(4)::c2
7+
end type
8+
end

flang/test/Evaluate/comporder.f90

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
!RUN: %flang_fc1 -fdebug-unparse -I%S/Inputs %s | FileCheck %s
2+
program main
3+
use comporder2
4+
type, extends(intermediate) :: last
5+
integer c3
6+
end type
7+
!CHECK:PRINT *, last(c1=1_4,c2=2_4,c3=3_4)
8+
print *, last(1,2,3)
9+
!CHECK:PRINT *, last(c1=11_4,c2=12_4,c3=13_4)
10+
print *, last(c3=13,c2=12,c1=11)
11+
!CHECK:PRINT *, last(c1=21_4,c2=22_4,c3=23_4)
12+
print *, last(c3=23,c1=21,c2=22)
13+
!CHECK:PRINT *, last(c1=31_4,c2=32_4,c3=33_4)
14+
print *, last(c2=32,c3=33,c1=31)
15+
!CHECK:PRINT *, last(c1=41_4,c2=42_4,c3=43_4)
16+
print *, last(c2=42,c1=41,c3=43)
17+
!CHECK:PRINT *, last(c1=51_4,c2=52_4,c3=53_4)
18+
print *, last(c1=51,c3=53,c2=52)
19+
!CHECK:PRINT *, last(c1=61_4,c2=62_4,c3=63_4)
20+
print *, last(c1=61,c2=62,c3=63)
21+
!CHECK:PRINT *, last(intermediate=intermediate(c1=71_4,c2=72_4),c3=73_4)
22+
print *, last(c3=73,intermediate=intermediate(c2=72,c1=71))
23+
!CHECK:PRINT *, last(intermediate=intermediate(c1=81_4,c2=82_4),c3=83_4)
24+
print *, last(c3=83,intermediate=intermediate(c1=81,c2=82))
25+
!CHECK:PRINT *, last(intermediate=intermediate(c1=91_4,c2=92_4),c3=93_4)
26+
print *, last(intermediate(c2=92,c1=91),c3=93)
27+
!CHECK:PRINT *, last(intermediate=intermediate(c1=101_4,c2=102_4),c3=103_4)
28+
print *, last(intermediate(c1=101,c2=102),c3=103)
29+
!CHECK:PRINT *, last(intermediate=intermediate(base=base(c1=111_4),c2=112_4),c3=113_4)
30+
print *, last(c3=113,intermediate=intermediate(c2=112,base=base(c1=111)))
31+
!CHECK:PRINT *, last(intermediate=intermediate(base=base(c1=121_4),c2=122_4),c3=123_4)
32+
print *, last(c3=123,intermediate=intermediate(base(c1=121),c2=122))
33+
!CHECK:PRINT *, last(intermediate=intermediate(base=base(c1=131_4),c2=132_4),c3=133_4)
34+
print *, last(intermediate(c2=132,base=base(c1=131)),c3=133)
35+
!CHECK:PRINT *, last(intermediate=intermediate(base=base(c1=141_4),c2=142_4),c3=143_4)
36+
print *, last(intermediate(base(c1=141),c2=142),c3=143)
37+
!CHECK:PRINT *, last(base=base(c1=151_4),c2=152_4,c3=153_4)
38+
print *, last(base(151),c3=153,c2=152)
39+
!CHECK:PRINT *, last(base=base(c1=161_4),c2=162_4,c3=163_4)
40+
print *, last(base(161),c2=162,c3=163)
41+
end

0 commit comments

Comments
 (0)