Skip to content

Commit 189d89a

Browse files
authored
[flang] Ensure names resolve in DATA statement objects (#82825)
When DATA statement objects have derived types obtained by implicit typing rules, their types aren't known until specification part processing is complete. In the case of a derived type, any component name in a designator may still be in need of name resolution. Take care of it in the deferred check visitor that runs at the end of name resolution in each specification and execution part. Fixes #82069.
1 parent 21c83fe commit 189d89a

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9095,6 +9095,8 @@ void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) {
90959095
// pointers, are deferred until all of the pertinent specification parts
90969096
// have been visited. This deferred processing enables the use of forward
90979097
// references in these circumstances.
9098+
// Data statement objects with implicit derived types are finally
9099+
// resolved here.
90989100
class DeferredCheckVisitor {
90999101
public:
91009102
explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver)
@@ -9110,16 +9112,17 @@ class DeferredCheckVisitor {
91109112
if (Symbol * symbol{name.symbol}) {
91119113
if (Scope * scope{symbol->scope()}) {
91129114
if (scope->IsDerivedType()) {
9113-
resolver_.PushScope(*scope);
9114-
pushedScope_ = true;
9115+
CHECK(outerScope_ == nullptr);
9116+
outerScope_ = &resolver_.currScope();
9117+
resolver_.SetScope(*scope);
91159118
}
91169119
}
91179120
}
91189121
}
91199122
void Post(const parser::EndTypeStmt &) {
9120-
if (pushedScope_) {
9121-
resolver_.PopScope();
9122-
pushedScope_ = false;
9123+
if (outerScope_) {
9124+
resolver_.SetScope(*outerScope_);
9125+
outerScope_ = nullptr;
91239126
}
91249127
}
91259128

@@ -9149,10 +9152,20 @@ class DeferredCheckVisitor {
91499152
resolver_.CheckExplicitInterface(tbps.interfaceName);
91509153
}
91519154
void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
9152-
if (pushedScope_) {
9155+
if (outerScope_) {
91539156
resolver_.CheckBindings(tbps);
91549157
}
91559158
}
9159+
bool Pre(const parser::DataStmtObject &) {
9160+
++dataStmtObjectNesting_;
9161+
return true;
9162+
}
9163+
void Post(const parser::DataStmtObject &) { --dataStmtObjectNesting_; }
9164+
void Post(const parser::Designator &x) {
9165+
if (dataStmtObjectNesting_ > 0) {
9166+
resolver_.ResolveDesignator(x);
9167+
}
9168+
}
91569169

91579170
private:
91589171
void Init(const parser::Name &name,
@@ -9174,7 +9187,8 @@ class DeferredCheckVisitor {
91749187
}
91759188

91769189
ResolveNamesVisitor &resolver_;
9177-
bool pushedScope_{false};
9190+
Scope *outerScope_{nullptr};
9191+
int dataStmtObjectNesting_{0};
91789192
};
91799193

91809194
// Perform checks and completions that need to happen after all of

flang/test/Semantics/data22.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
2+
! Ensure that implicitly typed DATA statement objects with derived
3+
! types get their symbols resolved by the end of the name resolution pass.
4+
! CHECK: x1 (Implicit, InDataStmt) size=4 offset=0: ObjectEntity type: TYPE(t1) shape: 1_8:1_8 init:[t1::t1(n=123_4)]
5+
! CHECK: x2 (InDataStmt) size=4 offset=4: ObjectEntity type: TYPE(t2) shape: 1_8:1_8 init:[t2::t2(m=456_4)]
6+
implicit type(t1)(x)
7+
type t1
8+
integer n
9+
end type
10+
dimension x1(1), x2(1)
11+
data x1(1)%n /123/
12+
data x2(1)%m /456/
13+
type t2
14+
integer m
15+
end type
16+
type(t2) x2
17+
end

0 commit comments

Comments
 (0)