Skip to content

Commit bebbe64

Browse files
committed
[flang] Fix creation of deferred shape arrays by POINTER statement
It's possible to declare deferred shape array using the POINTER statement, for example: POINTER :: var(:) When analyzing POINTER declarations, we were not capturing the array specification information, if present. I fixed this by changing the "Post" function for "parser::PointerDecl" to check to see if the declaration contained a "DeferredShapeSpecList". In such cases, I analyzed the shape and used to information to declare an "ObjectEntity" that contains the shape information rather than an "UnknownEntity". I also added a couple of small tests that fail to compile without these changes. Differential Revision: https://reviews.llvm.org/D95080
1 parent 33a5d21 commit bebbe64

File tree

4 files changed

+32
-3
lines changed

4 files changed

+32
-3
lines changed

flang/lib/Semantics/resolve-names-utils.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class ArraySpecAnalyzer {
219219
public:
220220
ArraySpecAnalyzer(SemanticsContext &context) : context_{context} {}
221221
ArraySpec Analyze(const parser::ArraySpec &);
222+
ArraySpec AnalyzeDeferredShapeSpecList(const parser::DeferredShapeSpecList &);
222223
ArraySpec Analyze(const parser::ComponentArraySpec &);
223224
ArraySpec Analyze(const parser::CoarraySpec &);
224225

@@ -252,6 +253,11 @@ ArraySpec AnalyzeArraySpec(
252253
SemanticsContext &context, const parser::ComponentArraySpec &arraySpec) {
253254
return ArraySpecAnalyzer{context}.Analyze(arraySpec);
254255
}
256+
ArraySpec AnalyzeDeferredShapeSpecList(SemanticsContext &context,
257+
const parser::DeferredShapeSpecList &deferredShapeSpecs) {
258+
return ArraySpecAnalyzer{context}.AnalyzeDeferredShapeSpecList(
259+
deferredShapeSpecs);
260+
}
255261
ArraySpec AnalyzeCoarraySpec(
256262
SemanticsContext &context, const parser::CoarraySpec &coarraySpec) {
257263
return ArraySpecAnalyzer{context}.Analyze(coarraySpec);
@@ -275,6 +281,12 @@ ArraySpec ArraySpecAnalyzer::Analyze(const parser::ArraySpec &x) {
275281
CHECK(!arraySpec_.empty());
276282
return arraySpec_;
277283
}
284+
ArraySpec ArraySpecAnalyzer::AnalyzeDeferredShapeSpecList(
285+
const parser::DeferredShapeSpecList &x) {
286+
Analyze(x);
287+
CHECK(!arraySpec_.empty());
288+
return arraySpec_;
289+
}
278290
ArraySpec ArraySpecAnalyzer::Analyze(const parser::CoarraySpec &x) {
279291
std::visit(
280292
common::visitors{

flang/lib/Semantics/resolve-names-utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class GenericSpecInfo {
100100
ArraySpec AnalyzeArraySpec(SemanticsContext &, const parser::ArraySpec &);
101101
ArraySpec AnalyzeArraySpec(
102102
SemanticsContext &, const parser::ComponentArraySpec &);
103+
ArraySpec AnalyzeDeferredShapeSpecList(
104+
SemanticsContext &, const parser::DeferredShapeSpecList &);
103105
ArraySpec AnalyzeCoarraySpec(
104106
SemanticsContext &context, const parser::CoarraySpec &);
105107

flang/lib/Semantics/resolve-names.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ class ArraySpecVisitor : public virtual BaseVisitor {
429429

430430
protected:
431431
const ArraySpec &arraySpec();
432+
void set_arraySpec(const ArraySpec arraySpec) { arraySpec_ = arraySpec; }
432433
const ArraySpec &coarraySpec();
433434
void BeginArraySpec();
434435
void EndArraySpec();
@@ -3250,8 +3251,18 @@ void DeclarationVisitor::Post(const parser::EntityDecl &x) {
32503251

32513252
void DeclarationVisitor::Post(const parser::PointerDecl &x) {
32523253
const auto &name{std::get<parser::Name>(x.t)};
3253-
Symbol &symbol{DeclareUnknownEntity(name, Attrs{Attr::POINTER})};
3254-
symbol.ReplaceName(name.source);
3254+
if (const auto &deferredShapeSpecs{
3255+
std::get<std::optional<parser::DeferredShapeSpecList>>(x.t)}) {
3256+
CHECK(arraySpec().empty());
3257+
BeginArraySpec();
3258+
set_arraySpec(AnalyzeDeferredShapeSpecList(context(), *deferredShapeSpecs));
3259+
Symbol &symbol{DeclareObjectEntity(name, Attrs{Attr::POINTER})};
3260+
symbol.ReplaceName(name.source);
3261+
EndArraySpec();
3262+
} else {
3263+
Symbol &symbol{DeclareUnknownEntity(name, Attrs{Attr::POINTER})};
3264+
symbol.ReplaceName(name.source);
3265+
}
32553266
}
32563267

32573268
bool DeclarationVisitor::Pre(const parser::BindEntity &x) {

flang/test/Semantics/allocate12.f90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
! RUN: %S/test_errors.sh %s %t %f18
22
! Check for semantic errors in ALLOCATE statements
33

4-
subroutine C941_C942b_C950(xsrc, x1, a2, b2, cx1, ca2, cb1, cb2, c1)
4+
subroutine C941_C942b_C950(xsrc, x1, a2, b2, cx1, ca2, cb1, cb2, c1, c2)
55
! C941: An allocate-coarray-spec shall appear if and only if the allocate-object
66
! is a coarray.
77
type type0
@@ -40,6 +40,8 @@ subroutine C941_C942b_C950(xsrc, x1, a2, b2, cx1, ca2, cb1, cb2, c1)
4040
type(B) :: cb1[5:*], cb2(*)[2, -1:*]
4141

4242
type(C) :: c1
43+
pointer :: c2(:, :)
44+
pointer :: varLocal(:)
4345

4446
class(*), allocatable :: var(:), cvar(:)[:]
4547

@@ -48,6 +50,8 @@ subroutine C941_C942b_C950(xsrc, x1, a2, b2, cx1, ca2, cb1, cb2, c1)
4850
allocate(a1, a2(10), ca1[2, -1:*], ca2(10)[*])
4951
allocate(b1%x, b2(1)%x, cb1%x, cb2(1)%x, SOURCE=xsrc)
5052
allocate(c1%x(-1:10, 1:5), c1%cx(-1:10, 1:5)[-1:5, 1:2, 2:*])
53+
allocate(c2(9, 27))
54+
allocate(varLocal(64))
5155
allocate(A:: var(5), cvar(10)[*])
5256

5357

0 commit comments

Comments
 (0)