Skip to content

Commit d732c86

Browse files
authored
[flang] Don't take corank from actual intrinsic argument (llvm#124029)
When constructing the characteristics of a particular reference to an intrinsic procedure that was passed a non-coindexed reference to local coarray data as an actual argument, don't add the corank of the actual argument to those characteristics. Also clean up the TypeAndShape characteristics class a little; the Attr::Coarray is redundant since the corank() accessor can be used to the same effect.
1 parent 1e9b60c commit d732c86

File tree

6 files changed

+22
-23
lines changed

6 files changed

+22
-23
lines changed

flang/include/flang/Evaluate/characteristics.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ bool ShapesAreCompatible(const std::optional<Shape> &,
6060

6161
class TypeAndShape {
6262
public:
63-
ENUM_CLASS(
64-
Attr, AssumedRank, AssumedShape, AssumedSize, DeferredShape, Coarray)
63+
ENUM_CLASS(Attr, AssumedRank, AssumedShape, AssumedSize, DeferredShape)
6564
using Attrs = common::EnumSet<Attr, Attr_enumSize>;
6665

6766
explicit TypeAndShape(DynamicType t) : type_{t}, shape_{Shape{}} {
@@ -103,9 +102,6 @@ class TypeAndShape {
103102
if (auto type{x.GetType()}) {
104103
TypeAndShape result{*type, GetShape(context, x, invariantOnly)};
105104
result.corank_ = GetCorank(x);
106-
if (result.corank_ > 0) {
107-
result.attrs_.set(Attr::Coarray);
108-
}
109105
if (type->category() == TypeCategory::Character) {
110106
if (const auto *chExpr{UnwrapExpr<Expr<SomeCharacter>>(x)}) {
111107
if (auto length{chExpr->LEN()}) {
@@ -179,14 +175,14 @@ class TypeAndShape {
179175
const std::optional<Shape> &shape() const { return shape_; }
180176
const Attrs &attrs() const { return attrs_; }
181177
int corank() const { return corank_; }
178+
void set_corank(int n) { corank_ = n; }
182179

183180
// Return -1 for assumed-rank as a safety.
184181
int Rank() const { return shape_ ? GetRank(*shape_) : -1; }
185182

186183
// Can sequence association apply to this argument?
187184
bool CanBeSequenceAssociated() const {
188-
constexpr Attrs notAssumedOrExplicitShape{
189-
~Attrs{Attr::AssumedSize, Attr::Coarray}};
185+
constexpr Attrs notAssumedOrExplicitShape{~Attrs{Attr::AssumedSize}};
190186
return Rank() > 0 && (attrs() & notAssumedOrExplicitShape).none();
191187
}
192188

flang/lib/Evaluate/characteristics.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,8 @@ void TypeAndShape::AcquireAttrs(const semantics::Symbol &symbol) {
227227
} else if (semantics::IsAssumedSizeArray(symbol)) {
228228
attrs_.set(Attr::AssumedSize);
229229
}
230-
if (int n{GetCorank(symbol)}) {
231-
corank_ = n;
232-
attrs_.set(Attr::Coarray);
230+
if (int corank{GetCorank(symbol)}; corank > 0) {
231+
corank_ = corank;
233232
}
234233
if (const auto *object{
235234
symbol.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()};
@@ -439,9 +438,9 @@ bool DummyDataObject::CanBePassedViaImplicitInterface(
439438
return false; // 15.4.2.2(3)(a)
440439
} else if ((type.attrs() &
441440
TypeAndShape::Attrs{TypeAndShape::Attr::AssumedShape,
442-
TypeAndShape::Attr::AssumedRank,
443-
TypeAndShape::Attr::Coarray})
444-
.any()) {
441+
TypeAndShape::Attr::AssumedRank})
442+
.any() ||
443+
type.corank() > 0) {
445444
if (whyNot) {
446445
*whyNot = "a dummy argument is assumed-shape, assumed-rank, or a coarray";
447446
}
@@ -471,14 +470,15 @@ bool DummyDataObject::CanBePassedViaImplicitInterface(
471470
}
472471

473472
bool DummyDataObject::IsPassedByDescriptor(bool isBindC) const {
474-
constexpr TypeAndShape::Attrs shapeRequiringBox = {
473+
constexpr TypeAndShape::Attrs shapeRequiringBox{
475474
TypeAndShape::Attr::AssumedShape, TypeAndShape::Attr::DeferredShape,
476-
TypeAndShape::Attr::AssumedRank, TypeAndShape::Attr::Coarray};
475+
TypeAndShape::Attr::AssumedRank};
477476
if ((attrs & Attrs{Attr::Allocatable, Attr::Pointer}).any()) {
478477
return true;
479478
} else if ((type.attrs() & shapeRequiringBox).any()) {
480-
// Need to pass shape/coshape info in a descriptor.
481-
return true;
479+
return true; // pass shape in descriptor
480+
} else if (type.corank() > 0) {
481+
return true; // pass coshape in descriptor
482482
} else if (type.type().IsPolymorphic() && !type.type().IsAssumedType()) {
483483
// Need to pass dynamic type info in a descriptor.
484484
return true;

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,6 +2576,10 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
25762576
// Dummy procedures are never elemental.
25772577
dummyProc->procedure.value().attrs.reset(
25782578
characteristics::Procedure::Attr::Elemental);
2579+
} else if (auto *dummyObject{
2580+
std::get_if<characteristics::DummyDataObject>(
2581+
&dc->u)}) {
2582+
dummyObject->type.set_corank(0);
25792583
}
25802584
dummyArgs.emplace_back(std::move(*dc));
25812585
if (d.typePattern.kindCode == KindCode::same && !sameDummyArg) {

flang/lib/Lower/CallInterface.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,10 +1132,7 @@ class Fortran::lower::CallInterfaceImpl {
11321132

11331133
// TODO: intents that require special care (e.g finalization)
11341134

1135-
using ShapeAttr = Fortran::evaluate::characteristics::TypeAndShape::Attr;
1136-
const Fortran::evaluate::characteristics::TypeAndShape::Attrs &shapeAttrs =
1137-
obj.type.attrs();
1138-
if (shapeAttrs.test(ShapeAttr::Coarray))
1135+
if (obj.type.corank() > 0)
11391136
TODO(loc, "coarray: dummy argument coarray in procedure interface");
11401137

11411138
// So far assume that if the argument cannot be passed by implicit interface

flang/lib/Semantics/check-call.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ static bool CanAssociateWithStorageSequence(
112112
characteristics::TypeAndShape::Attr::AssumedRank) &&
113113
!dummy.type.attrs().test(
114114
characteristics::TypeAndShape::Attr::AssumedShape) &&
115-
!dummy.type.attrs().test(characteristics::TypeAndShape::Attr::Coarray) &&
116115
!dummy.attrs.test(characteristics::DummyDataObject::Attr::Allocatable) &&
117-
!dummy.attrs.test(characteristics::DummyDataObject::Attr::Pointer);
116+
!dummy.attrs.test(characteristics::DummyDataObject::Attr::Pointer) &&
117+
dummy.type.corank() == 0;
118118
}
119119

120120
// When a CHARACTER actual argument is known to be short,

flang/test/Semantics/call08.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ subroutine test(x,c3,c4)
2626
real :: x(:)[*]
2727
real, intent(in) :: c3(:)[*]
2828
real, contiguous, intent(in) :: c4(:)[*]
29+
character(2) :: coarr(2)[*] = [ "ab", "cd" ]
2930
call s01(c1) ! ok
3031
call s02(c2) ! ok
3132
call s03(c4) ! ok
@@ -44,5 +45,6 @@ subroutine test(x,c3,c4)
4445
call s04(c3)
4546
!ERROR: Actual argument associated with coarray dummy argument 'x=' (not assumed shape or rank) must be simply contiguous
4647
call s04(x)
48+
print *, ichar(coarr(:)(1:1)) ! ok, ensure no bogus contiguity error
4749
end subroutine
4850
end module

0 commit comments

Comments
 (0)