1313#include " flang/Parser/parse-tree.h"
1414#include " flang/Semantics/expression.h"
1515#include " flang/Semantics/tools.h"
16+ #include < optional>
1617
1718namespace Fortran ::semantics {
1819
1920void DeallocateChecker::Leave (const parser::DeallocateStmt &deallocateStmt) {
2021 bool gotStat{false }, gotMsg{false };
21- const parser::Name *statVar{nullptr }, *msgVar{nullptr };
22+ const SomeExpr *statVar{nullptr }, *msgVar{nullptr };
23+ std::optional<parser::CharBlock> statSource;
24+ std::optional<parser::CharBlock> msgSource;
2225 for (const parser::StatOrErrmsg &deallocOpt :
2326 std::get<std::list<parser::StatOrErrmsg>>(deallocateStmt.t )) {
2427 common::visit (
@@ -28,11 +31,9 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
2831 context_.Say (
2932 " STAT may not be duplicated in a DEALLOCATE statement" _err_en_US);
3033 }
31- if (const auto *designator{
32- parser::Unwrap<parser::Designator>(var)}) {
33- statVar = &parser::GetLastName (*designator);
34- }
3534 gotStat = true ;
35+ statVar = GetExpr (context_, var);
36+ statSource = parser::Unwrap<parser::Variable>(var)->GetSource ();
3637 },
3738 [&](const parser::MsgVariable &var) {
3839 WarnOnDeferredLengthCharacterScalar (context_,
@@ -43,51 +44,49 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
4344 context_.Say (
4445 " ERRMSG may not be duplicated in a DEALLOCATE statement" _err_en_US);
4546 }
46- if (const auto *designator{
47- parser::Unwrap<parser::Designator>(var)}) {
48- msgVar = &parser::GetLastName (*designator);
49- }
5047 gotMsg = true ;
48+ msgVar = GetExpr (context_, var);
49+ msgSource = parser::Unwrap<parser::Variable>(var)->GetSource ();
5150 },
5251 },
5352 deallocOpt.u );
5453 }
5554 for (const parser::AllocateObject &allocateObject :
5655 std::get<std::list<parser::AllocateObject>>(deallocateStmt.t )) {
57- const Symbol *ultimate{ nullptr } ;
56+ parser::CharBlock source ;
5857 common::visit (
5958 common::visitors{
6059 [&](const parser::Name &name) {
61- if (name. symbol ) {
62- ultimate = &name.symbol ->GetUltimate ();
63- }
64- if (context_.HasError (ultimate )) {
60+ const Symbol *symbol {
61+ name. symbol ? &name.symbol ->GetUltimate () : nullptr } ;
62+ source = name. source ;
63+ if (context_.HasError (symbol )) {
6564 // already reported an error
66- } else if (!IsVariableName (*ultimate )) {
67- context_.Say (name. source ,
65+ } else if (!IsVariableName (*symbol )) {
66+ context_.Say (source,
6867 " Name in DEALLOCATE statement must be a variable name" _err_en_US);
69- } else if (!IsAllocatableOrObjectPointer (ultimate )) { // C936
70- context_.Say (name. source ,
68+ } else if (!IsAllocatableOrObjectPointer (symbol )) { // C936
69+ context_.Say (source,
7170 " Name in DEALLOCATE statement must have the ALLOCATABLE or POINTER attribute" _err_en_US);
72- } else if (auto whyNot{WhyNotDefinable (name. source ,
73- context_.FindScope (name. source ),
74- {DefinabilityFlag::PointerDefinition,
75- DefinabilityFlag::AcceptAllocatable,
76- DefinabilityFlag::PotentialDeallocation},
77- *ultimate )}) {
71+ } else if (auto whyNot{
72+ WhyNotDefinable (source, context_.FindScope (source),
73+ {DefinabilityFlag::PointerDefinition,
74+ DefinabilityFlag::AcceptAllocatable,
75+ DefinabilityFlag::PotentialDeallocation},
76+ *symbol )}) {
7877 // Catch problems with non-definability of the
7978 // pointer/allocatable
8079 context_
81- .Say (name. source ,
80+ .Say (source,
8281 " Name in DEALLOCATE statement is not definable" _err_en_US)
8382 .Attach (std::move (
8483 whyNot->set_severity (parser::Severity::Because)));
85- } else if (auto whyNot{WhyNotDefinable (name. source ,
86- context_.FindScope (name. source ),
87- DefinabilityFlags{}, *ultimate )}) {
84+ } else if (auto whyNot{
85+ WhyNotDefinable (source, context_.FindScope (source),
86+ DefinabilityFlags{}, *symbol )}) {
8887 // Catch problems with non-definability of the dynamic object
8988 context_
90- .Say (name. source ,
89+ .Say (source,
9190 " Object in DEALLOCATE statement is not deallocatable" _err_en_US)
9291 .Attach (std::move (
9392 whyNot->set_severity (parser::Severity::Because)));
@@ -98,12 +97,13 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
9897 [&](const parser::StructureComponent &structureComponent) {
9998 // Only perform structureComponent checks if it was successfully
10099 // analyzed by expression analysis.
101- auto source{structureComponent.component .source };
102- if (structureComponent.component .symbol ) {
103- ultimate = &structureComponent.component .symbol ->GetUltimate ();
104- }
100+ source = structureComponent.component .source ;
105101 if (const auto *expr{GetExpr (context_, allocateObject)}) {
106- if (!IsAllocatableOrObjectPointer (ultimate)) { // F'2023 C936
102+ if (const Symbol *symbol{structureComponent.component .symbol
103+ ? &structureComponent.component .symbol
104+ ->GetUltimate ()
105+ : nullptr };
106+ !IsAllocatableOrObjectPointer (symbol)) { // F'2023 C936
107107 context_.Say (source,
108108 " Component in DEALLOCATE statement must have the ALLOCATABLE or POINTER attribute" _err_en_US);
109109 } else if (auto whyNot{WhyNotDefinable (source,
@@ -133,20 +133,14 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
133133 },
134134 },
135135 allocateObject.u );
136- if (ultimate) {
137- if (gotStat && statVar) {
138- if (const Symbol *symbol{statVar->symbol };
139- symbol && *ultimate == symbol->GetUltimate ()) {
140- context_.Say (statVar->source ,
141- " STAT variable in DEALLOCATE must not be the variable being deallocated" _err_en_US);
142- }
136+ if (const SomeExpr *allocObj{GetExpr (context_, allocateObject)}) {
137+ if (statVar && *allocObj == *statVar) {
138+ context_.Say (statSource.value_or (source),
139+ " STAT variable in DEALLOCATE must not be the variable being deallocated" _err_en_US);
143140 }
144- if (gotMsg && msgVar) {
145- if (const Symbol *symbol{msgVar->symbol };
146- symbol && *ultimate == symbol->GetUltimate ()) {
147- context_.Say (msgVar->source ,
148- " ERRMSG variable in DEALLOCATE must not be the variable being deallocated" _err_en_US);
149- }
141+ if (msgVar && *allocObj == *msgVar) {
142+ context_.Say (msgSource.value_or (source),
143+ " ERRMSG variable in DEALLOCATE must not be the variable being deallocated" _err_en_US);
150144 }
151145 }
152146 }
0 commit comments