Skip to content

Commit fd66fa5

Browse files
authored
[flang] Retrieve shape from selector when generating assoc sym type (#137117)
This PR extends `genSymbolType` so that the type of an associating symbol carries the shape of the selector expression, if any. This is a fix for a bug that triggered when an associating symbol is used in a locality specifier. For example, given the following input: ```fortran associate(a => aa(4:)) do concurrent (i = 4:11) local(a) a(i) = 0 end do end associate ``` before the changes in the PR, flang would assert that we are casting between incompatible types. The issue happened since for the associating symbol (`a`), flang generated its type as `f32` rather than `!fir.array<8xf32>` as it should be in this case.
1 parent dec8f13 commit fd66fa5

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

flang/lib/Lower/ConvertType.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,19 +276,23 @@ struct TypeBuilderImpl {
276276
} else {
277277
fir::emitFatalError(loc, "symbol must have a type");
278278
}
279-
bool isPolymorphic = (Fortran::semantics::IsPolymorphic(symbol) ||
280-
Fortran::semantics::IsUnlimitedPolymorphic(symbol)) &&
281-
!Fortran::semantics::IsAssumedType(symbol);
282-
if (ultimate.IsObjectArray()) {
283-
auto shapeExpr =
284-
Fortran::evaluate::GetShape(converter.getFoldingContext(), ultimate);
279+
280+
auto shapeExpr =
281+
Fortran::evaluate::GetShape(converter.getFoldingContext(), ultimate);
282+
283+
if (shapeExpr && !shapeExpr->empty()) {
284+
// Statically ranked array.
285285
fir::SequenceType::Shape shape;
286-
// If there is no shapExpr, this is an assumed-rank, and the empty shape
287-
// will build the desired fir.array<*:T> type.
288-
if (shapeExpr)
289-
translateShape(shape, std::move(*shapeExpr));
286+
translateShape(shape, std::move(*shapeExpr));
290287
ty = fir::SequenceType::get(shape, ty);
288+
} else if (!shapeExpr) {
289+
// Assumed-rank.
290+
ty = fir::SequenceType::get(fir::SequenceType::Shape{}, ty);
291291
}
292+
293+
bool isPolymorphic = (Fortran::semantics::IsPolymorphic(symbol) ||
294+
Fortran::semantics::IsUnlimitedPolymorphic(symbol)) &&
295+
!Fortran::semantics::IsAssumedType(symbol);
292296
if (Fortran::semantics::IsPointer(symbol))
293297
return fir::wrapInClassOrBoxType(fir::PointerType::get(ty),
294298
isPolymorphic);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
2+
3+
subroutine local_assoc
4+
implicit none
5+
integer i
6+
real, dimension(2:11) :: aa
7+
8+
associate(a => aa(4:))
9+
do concurrent (i = 4:11) local(a)
10+
a(i) = 0
11+
end do
12+
end associate
13+
end subroutine local_assoc
14+
15+
! CHECK: %[[C8:.*]] = arith.constant 8 : index
16+
17+
! CHECK: fir.do_concurrent.loop {{.*}} {
18+
! CHECK: %[[LOCAL_ALLOC:.*]] = fir.alloca !fir.array<8xf32> {bindc_name = "a", pinned, uniq_name = "{{.*}}local_assocEa"}
19+
! CHECK: %[[LOCAL_SHAPE:.*]] = fir.shape %[[C8]] :
20+
! CHECK: %[[LOCAL_DECL:.*]]:2 = hlfir.declare %[[LOCAL_ALLOC]](%[[LOCAL_SHAPE]])
21+
! CHECK: hlfir.designate %[[LOCAL_DECL]]#0 (%{{.*}})
22+
! CHECK: }

0 commit comments

Comments
 (0)