Skip to content

Commit dab1148

Browse files
authored
[flang] Address OpenACC name resolution gaps (#164313)
Some OpenACC parsers aren't filling in the "source" data members of parse tree nodes, or not doing so correctly; and some of those nodes are not adding their source data members to the source ranges of the current scope when being visited in name resolution, which causes SemanticsContext::FindScope() to misidentify the current scope in directive resolution when creating contexts. Further, the name resolution for a "use_device" clause isn't walking its subtrees, so some parser::Name nodes are not being resolved to Symbols. Fix these problems, and clean up resolve-directives.cpp a bit, since most Name nodes don't need to have their symbol table pointers updated now.
1 parent 41cc0de commit dab1148

File tree

7 files changed

+134
-92
lines changed

7 files changed

+134
-92
lines changed

flang/include/flang/Semantics/semantics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ class SemanticsContext {
262262
const Scope &FindScope(parser::CharBlock) const;
263263
Scope &FindScope(parser::CharBlock);
264264
void UpdateScopeIndex(Scope &, parser::CharBlock);
265+
void DumpScopeIndex(llvm::raw_ostream &) const;
265266

266267
bool IsInModuleFile(parser::CharBlock) const;
267268

flang/lib/Parser/openacc-parsers.cpp

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,21 @@ TYPE_PARSER(
7575
// tile size is one of:
7676
// * (represented as an empty std::optional<ScalarIntExpr>)
7777
// constant-int-expr
78-
TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) ||
78+
TYPE_PARSER(sourced(construct<AccTileExpr>(scalarIntConstantExpr) ||
7979
construct<AccTileExpr>(
80-
"*" >> construct<std::optional<ScalarIntConstantExpr>>()))
80+
"*" >> construct<std::optional<ScalarIntConstantExpr>>())))
8181
TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{})))
8282

8383
// 2.9 (1979-1982) gang-arg is one of :
8484
// [num:]int-expr
8585
// dim:int-expr
8686
// static:size-expr
87-
TYPE_PARSER(construct<AccGangArg>(construct<AccGangArg::Static>(
88-
"STATIC: " >> Parser<AccSizeExpr>{})) ||
87+
TYPE_PARSER(sourced(construct<AccGangArg>(construct<AccGangArg::Static>(
88+
"STATIC: " >> Parser<AccSizeExpr>{})) ||
8989
construct<AccGangArg>(
9090
construct<AccGangArg::Dim>("DIM: " >> scalarIntExpr)) ||
9191
construct<AccGangArg>(
92-
construct<AccGangArg::Num>(maybe("NUM: "_tok) >> scalarIntExpr)))
92+
construct<AccGangArg::Num>(maybe("NUM: "_tok) >> scalarIntExpr))))
9393

9494
// 2.9 gang-arg-list
9595
TYPE_PARSER(
@@ -101,7 +101,7 @@ TYPE_PARSER(construct<AccCollapseArg>(
101101

102102
// 2.5.15 Reduction, F'2023 R1131, and CUF reduction-op
103103
// Operator for reduction
104-
TYPE_PARSER(sourced(construct<ReductionOperator>(
104+
TYPE_PARSER(construct<ReductionOperator>(
105105
first("+" >> pure(ReductionOperator::Operator::Plus),
106106
"*" >> pure(ReductionOperator::Operator::Multiply),
107107
"MAX" >> pure(ReductionOperator::Operator::Max),
@@ -112,32 +112,32 @@ TYPE_PARSER(sourced(construct<ReductionOperator>(
112112
".AND." >> pure(ReductionOperator::Operator::And),
113113
".OR." >> pure(ReductionOperator::Operator::Or),
114114
".EQV." >> pure(ReductionOperator::Operator::Eqv),
115-
".NEQV." >> pure(ReductionOperator::Operator::Neqv)))))
115+
".NEQV." >> pure(ReductionOperator::Operator::Neqv))))
116116

117117
// 2.15.1 Bind clause
118-
TYPE_PARSER(sourced(construct<AccBindClause>(name)) ||
119-
sourced(construct<AccBindClause>(scalarDefaultCharExpr)))
118+
TYPE_PARSER(sourced(construct<AccBindClause>(name) ||
119+
construct<AccBindClause>(scalarDefaultCharExpr)))
120120

121121
// 2.5.16 Default clause
122-
TYPE_PARSER(construct<AccDefaultClause>(
122+
TYPE_PARSER(sourced(construct<AccDefaultClause>(
123123
first("NONE" >> pure(llvm::acc::DefaultValue::ACC_Default_none),
124-
"PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_present))))
124+
"PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_present)))))
125125

126126
// SELF clause is either a simple optional condition for compute construct
127127
// or a synonym of the HOST clause for the update directive 2.14.4 holding
128128
// an object list.
129-
TYPE_PARSER(
129+
TYPE_PARSER(sourced(
130130
construct<AccSelfClause>(Parser<AccObjectList>{}) / lookAhead(")"_tok) ||
131-
construct<AccSelfClause>(scalarLogicalExpr / lookAhead(")"_tok)) ||
131+
construct<AccSelfClause>(scalarLogicalExpr) / lookAhead(")"_tok) ||
132132
construct<AccSelfClause>(
133133
recovery(fail<std::optional<ScalarLogicalExpr>>(
134134
"logical expression or object list expected"_err_en_US),
135-
SkipTo<')'>{} >> pure<std::optional<ScalarLogicalExpr>>())))
135+
SkipTo<')'>{} >> pure<std::optional<ScalarLogicalExpr>>()))))
136136

137137
// Modifier for copyin, copyout, cache and create
138-
TYPE_PARSER(construct<AccDataModifier>(
138+
TYPE_PARSER(sourced(construct<AccDataModifier>(
139139
first("ZERO:" >> pure(AccDataModifier::Modifier::Zero),
140-
"READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly))))
140+
"READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly)))))
141141

142142
// Combined directives
143143
TYPE_PARSER(sourced(construct<AccCombinedDirective>(
@@ -166,14 +166,13 @@ TYPE_PARSER(sourced(construct<AccStandaloneDirective>(
166166
TYPE_PARSER(sourced(construct<AccLoopDirective>(
167167
first("LOOP" >> pure(llvm::acc::Directive::ACCD_loop)))))
168168

169-
TYPE_PARSER(construct<AccBeginLoopDirective>(
170-
sourced(Parser<AccLoopDirective>{}), Parser<AccClauseList>{}))
169+
TYPE_PARSER(sourced(construct<AccBeginLoopDirective>(
170+
Parser<AccLoopDirective>{}, Parser<AccClauseList>{})))
171171

172172
TYPE_PARSER(construct<AccEndLoop>("END LOOP"_tok))
173173

174174
TYPE_PARSER(construct<OpenACCLoopConstruct>(
175-
sourced(Parser<AccBeginLoopDirective>{} / endAccLine),
176-
maybe(Parser<DoConstruct>{}),
175+
Parser<AccBeginLoopDirective>{} / endAccLine, maybe(Parser<DoConstruct>{}),
177176
maybe(startAccLine >> Parser<AccEndLoop>{} / endAccLine)))
178177

179178
// 2.15.1 Routine directive
@@ -186,8 +185,8 @@ TYPE_PARSER(sourced(
186185
parenthesized(Parser<AccObjectListWithModifier>{}))))
187186

188187
// 2.11 Combined constructs
189-
TYPE_PARSER(construct<AccBeginCombinedDirective>(
190-
sourced(Parser<AccCombinedDirective>{}), Parser<AccClauseList>{}))
188+
TYPE_PARSER(sourced(construct<AccBeginCombinedDirective>(
189+
Parser<AccCombinedDirective>{}, Parser<AccClauseList>{})))
191190

192191
// 2.12 Atomic constructs
193192
TYPE_PARSER(construct<AccEndAtomic>(startAccLine >> "END ATOMIC"_tok))
@@ -213,10 +212,10 @@ TYPE_PARSER("ATOMIC" >>
213212
statement(assignmentStmt), Parser<AccEndAtomic>{} / endAccLine))
214213

215214
TYPE_PARSER(
216-
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{})) ||
217-
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{})) ||
218-
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{})) ||
219-
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{})))
215+
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{}) ||
216+
construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{}) ||
217+
construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{}) ||
218+
construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{})))
220219

221220
// 2.13 Declare constructs
222221
TYPE_PARSER(sourced(construct<AccDeclarativeDirective>(
@@ -250,18 +249,18 @@ TYPE_PARSER(construct<OpenACCBlockConstruct>(
250249
pure(llvm::acc::Directive::ACCD_data))))))
251250

252251
// Standalone constructs
253-
TYPE_PARSER(construct<OpenACCStandaloneConstruct>(
254-
sourced(Parser<AccStandaloneDirective>{}), Parser<AccClauseList>{}))
252+
TYPE_PARSER(sourced(construct<OpenACCStandaloneConstruct>(
253+
Parser<AccStandaloneDirective>{}, Parser<AccClauseList>{})))
255254

256255
// Standalone declarative constructs
257-
TYPE_PARSER(construct<OpenACCStandaloneDeclarativeConstruct>(
258-
sourced(Parser<AccDeclarativeDirective>{}), Parser<AccClauseList>{}))
256+
TYPE_PARSER(sourced(construct<OpenACCStandaloneDeclarativeConstruct>(
257+
Parser<AccDeclarativeDirective>{}, Parser<AccClauseList>{})))
259258

260259
TYPE_PARSER(startAccLine >>
261260
withMessage("expected OpenACC directive"_err_en_US,
262-
first(sourced(construct<OpenACCDeclarativeConstruct>(
263-
Parser<OpenACCStandaloneDeclarativeConstruct>{})),
264-
sourced(construct<OpenACCDeclarativeConstruct>(
261+
sourced(first(construct<OpenACCDeclarativeConstruct>(
262+
Parser<OpenACCStandaloneDeclarativeConstruct>{}),
263+
construct<OpenACCDeclarativeConstruct>(
265264
Parser<OpenACCRoutineConstruct>{})))))
266265

267266
TYPE_PARSER(sourced(construct<OpenACCEndConstruct>(
@@ -293,9 +292,9 @@ TYPE_PARSER(startAccLine >>
293292
"SERIAL"_tok >> maybe("LOOP"_tok) >>
294293
pure(llvm::acc::Directive::ACCD_serial_loop))))))
295294

296-
TYPE_PARSER(construct<OpenACCCombinedConstruct>(
297-
sourced(Parser<AccBeginCombinedDirective>{} / endAccLine),
295+
TYPE_PARSER(sourced(construct<OpenACCCombinedConstruct>(
296+
Parser<AccBeginCombinedDirective>{} / endAccLine,
298297
maybe(Parser<DoConstruct>{}),
299-
maybe(Parser<AccEndCombinedDirective>{} / endAccLine)))
298+
maybe(Parser<AccEndCombinedDirective>{} / endAccLine))))
300299

301300
} // namespace Fortran::parser

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,17 @@
3131
#include <list>
3232
#include <map>
3333

34+
namespace Fortran::semantics {
35+
3436
template <typename T>
35-
static Fortran::semantics::Scope *GetScope(
36-
Fortran::semantics::SemanticsContext &context, const T &x) {
37-
std::optional<Fortran::parser::CharBlock> source{GetLastSource(x)};
38-
return source ? &context.FindScope(*source) : nullptr;
37+
static Scope *GetScope(SemanticsContext &context, const T &x) {
38+
if (auto source{GetLastSource(x)}) {
39+
return &context.FindScope(*source);
40+
} else {
41+
return nullptr;
42+
}
3943
}
4044

41-
namespace Fortran::semantics {
42-
4345
template <typename T> class DirectiveAttributeVisitor {
4446
public:
4547
explicit DirectiveAttributeVisitor(SemanticsContext &context)
@@ -361,7 +363,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
361363
void ResolveAccObject(const parser::AccObject &, Symbol::Flag);
362364
Symbol *ResolveAcc(const parser::Name &, Symbol::Flag, Scope &);
363365
Symbol *ResolveAcc(Symbol &, Symbol::Flag, Scope &);
364-
Symbol *ResolveName(const parser::Name &, bool parentScope = false);
366+
Symbol *ResolveName(const parser::Name &);
365367
Symbol *ResolveFctName(const parser::Name &);
366368
Symbol *ResolveAccCommonBlockName(const parser::Name *);
367369
Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
@@ -1257,31 +1259,22 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCStandaloneConstruct &x) {
12571259
return true;
12581260
}
12591261

1260-
Symbol *AccAttributeVisitor::ResolveName(
1261-
const parser::Name &name, bool parentScope) {
1262-
Symbol *prev{currScope().FindSymbol(name.source)};
1263-
// Check in parent scope if asked for.
1264-
if (!prev && parentScope) {
1265-
prev = currScope().parent().FindSymbol(name.source);
1266-
}
1267-
if (prev != name.symbol) {
1268-
name.symbol = prev;
1269-
}
1270-
return prev;
1262+
Symbol *AccAttributeVisitor::ResolveName(const parser::Name &name) {
1263+
return name.symbol;
12711264
}
12721265

12731266
Symbol *AccAttributeVisitor::ResolveFctName(const parser::Name &name) {
12741267
Symbol *prev{currScope().FindSymbol(name.source)};
1275-
if (!prev || (prev && prev->IsFuncResult())) {
1268+
if (prev && prev->IsFuncResult()) {
12761269
prev = currScope().parent().FindSymbol(name.source);
1277-
if (!prev) {
1278-
prev = &context_.globalScope().MakeSymbol(
1279-
name.source, Attrs{}, ProcEntityDetails{});
1280-
}
12811270
}
1282-
if (prev != name.symbol) {
1283-
name.symbol = prev;
1271+
if (!prev) {
1272+
prev = &*context_.globalScope()
1273+
.try_emplace(name.source, ProcEntityDetails{})
1274+
.first->second;
12841275
}
1276+
CHECK(!name.symbol || name.symbol == prev);
1277+
name.symbol = prev;
12851278
return prev;
12861279
}
12871280

@@ -1388,9 +1381,8 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCRoutineConstruct &x) {
13881381
} else {
13891382
PushContext(verbatim.source, llvm::acc::Directive::ACCD_routine);
13901383
}
1391-
const auto &optName{std::get<std::optional<parser::Name>>(x.t)};
1392-
if (optName) {
1393-
if (Symbol *sym = ResolveFctName(*optName)) {
1384+
if (const auto &optName{std::get<std::optional<parser::Name>>(x.t)}) {
1385+
if (Symbol * sym{ResolveFctName(*optName)}) {
13941386
Symbol &ultimate{sym->GetUltimate()};
13951387
AddRoutineInfoToSymbol(ultimate, x);
13961388
} else {
@@ -1425,7 +1417,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
14251417
case llvm::acc::Directive::ACCD_kernels_loop:
14261418
case llvm::acc::Directive::ACCD_parallel_loop:
14271419
case llvm::acc::Directive::ACCD_serial_loop:
1428-
PushContext(combinedDir.source, combinedDir.v);
1420+
PushContext(x.source, combinedDir.v);
14291421
break;
14301422
default:
14311423
break;
@@ -1706,26 +1698,27 @@ void AccAttributeVisitor::Post(const parser::AccDefaultClause &x) {
17061698
}
17071699
}
17081700

1709-
// For OpenACC constructs, check all the data-refs within the constructs
1710-
// and adjust the symbol for each Name if necessary
17111701
void AccAttributeVisitor::Post(const parser::Name &name) {
1712-
auto *symbol{name.symbol};
1713-
if (symbol && WithinConstruct()) {
1714-
symbol = &symbol->GetUltimate();
1715-
if (!symbol->owner().IsDerivedType() && !symbol->has<ProcEntityDetails>() &&
1716-
!symbol->has<SubprogramDetails>() && !IsObjectWithVisibleDSA(*symbol)) {
1702+
if (name.symbol && WithinConstruct()) {
1703+
const Symbol &symbol{name.symbol->GetUltimate()};
1704+
if (!symbol.owner().IsDerivedType() && !symbol.has<ProcEntityDetails>() &&
1705+
!symbol.has<SubprogramDetails>() && !IsObjectWithVisibleDSA(symbol)) {
17171706
if (Symbol * found{currScope().FindSymbol(name.source)}) {
1718-
if (symbol != found) {
1719-
name.symbol = found; // adjust the symbol within region
1707+
if (&symbol != found) {
1708+
// adjust the symbol within the region
1709+
// TODO: why didn't name resolution set the right name originally?
1710+
name.symbol = found;
17201711
} else if (GetContext().defaultDSA == Symbol::Flag::AccNone) {
17211712
// 2.5.14.
17221713
context_.Say(name.source,
17231714
"The DEFAULT(NONE) clause requires that '%s' must be listed in a data-mapping clause"_err_en_US,
1724-
symbol->name());
1715+
symbol.name());
17251716
}
1717+
} else {
1718+
// TODO: assertion here? or clear name.symbol?
17261719
}
17271720
}
1728-
} // within OpenACC construct
1721+
}
17291722
}
17301723

17311724
Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
@@ -1810,13 +1803,11 @@ Symbol *AccAttributeVisitor::ResolveAcc(
18101803

18111804
Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
18121805
const parser::Name &name, Symbol::Flag accFlag) {
1813-
Symbol *prev{currScope().FindSymbol(name.source)};
1814-
if (!name.symbol || !prev) {
1806+
if (name.symbol) {
1807+
return DeclareOrMarkOtherAccessEntity(*name.symbol, accFlag);
1808+
} else {
18151809
return nullptr;
1816-
} else if (prev != name.symbol) {
1817-
name.symbol = prev;
18181810
}
1819-
return DeclareOrMarkOtherAccessEntity(*prev, accFlag);
18201811
}
18211812

18221813
Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
@@ -2990,6 +2981,7 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
29902981
}
29912982

29922983
Symbol *OmpAttributeVisitor::ResolveName(const parser::Name *name) {
2984+
// TODO: why is the symbol not properly resolved by name resolution?
29932985
if (auto *resolvedSymbol{
29942986
name ? GetContext().scope.FindSymbol(name->source) : nullptr}) {
29952987
name->symbol = resolvedSymbol;

0 commit comments

Comments
 (0)