Skip to content

Commit

Permalink
[flang] Ensure names resolve in DATA statement objects (#82825)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
klausler committed Mar 2, 2024
1 parent 21c83fe commit 189d89a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
28 changes: 21 additions & 7 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9095,6 +9095,8 @@ void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) {
// pointers, are deferred until all of the pertinent specification parts
// have been visited. This deferred processing enables the use of forward
// references in these circumstances.
// Data statement objects with implicit derived types are finally
// resolved here.
class DeferredCheckVisitor {
public:
explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver)
Expand All @@ -9110,16 +9112,17 @@ class DeferredCheckVisitor {
if (Symbol * symbol{name.symbol}) {
if (Scope * scope{symbol->scope()}) {
if (scope->IsDerivedType()) {
resolver_.PushScope(*scope);
pushedScope_ = true;
CHECK(outerScope_ == nullptr);
outerScope_ = &resolver_.currScope();
resolver_.SetScope(*scope);
}
}
}
}
void Post(const parser::EndTypeStmt &) {
if (pushedScope_) {
resolver_.PopScope();
pushedScope_ = false;
if (outerScope_) {
resolver_.SetScope(*outerScope_);
outerScope_ = nullptr;
}
}

Expand Down Expand Up @@ -9149,10 +9152,20 @@ class DeferredCheckVisitor {
resolver_.CheckExplicitInterface(tbps.interfaceName);
}
void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
if (pushedScope_) {
if (outerScope_) {
resolver_.CheckBindings(tbps);
}
}
bool Pre(const parser::DataStmtObject &) {
++dataStmtObjectNesting_;
return true;
}
void Post(const parser::DataStmtObject &) { --dataStmtObjectNesting_; }
void Post(const parser::Designator &x) {
if (dataStmtObjectNesting_ > 0) {
resolver_.ResolveDesignator(x);
}
}

private:
void Init(const parser::Name &name,
Expand All @@ -9174,7 +9187,8 @@ class DeferredCheckVisitor {
}

ResolveNamesVisitor &resolver_;
bool pushedScope_{false};
Scope *outerScope_{nullptr};
int dataStmtObjectNesting_{0};
};

// Perform checks and completions that need to happen after all of
Expand Down
17 changes: 17 additions & 0 deletions flang/test/Semantics/data22.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s
! Ensure that implicitly typed DATA statement objects with derived
! types get their symbols resolved by the end of the name resolution pass.
! CHECK: x1 (Implicit, InDataStmt) size=4 offset=0: ObjectEntity type: TYPE(t1) shape: 1_8:1_8 init:[t1::t1(n=123_4)]
! CHECK: x2 (InDataStmt) size=4 offset=4: ObjectEntity type: TYPE(t2) shape: 1_8:1_8 init:[t2::t2(m=456_4)]
implicit type(t1)(x)
type t1
integer n
end type
dimension x1(1), x2(1)
data x1(1)%n /123/
data x2(1)%m /456/
type t2
integer m
end type
type(t2) x2
end

0 comments on commit 189d89a

Please sign in to comment.