Skip to content

Commit 28d5082

Browse files
committed
[flang] Fix references to destroyed objects
ProgramTree instances are created as the value of a local variable in the Pre(const parser::ProgramUnit &) member function in name resolution. But references to these ProgramTree instances can persist in SubprogramNameDetails symbol table entries that might survive that function call's lifetime, and lead to trouble later when (e.g.) expression semantics needs to deal with a possible forward reference in a function reference in an expression being processed later in expression checking. So put those ProgramTree instances into a longer-lived linked list within the SemanticsContext. Might fix some weird crashes reported on big-endian targets (AIX & Solaris).
1 parent 70cbedc commit 28d5082

File tree

5 files changed

+19
-9
lines changed

5 files changed

+19
-9
lines changed

flang/lib/Semantics/program-tree.h renamed to flang/include/flang/Semantics/program-tree.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
#ifndef FORTRAN_SEMANTICS_PROGRAM_TREE_H_
1010
#define FORTRAN_SEMANTICS_PROGRAM_TREE_H_
1111

12+
#include "symbol.h"
1213
#include "flang/Parser/parse-tree.h"
13-
#include "flang/Semantics/symbol.h"
1414
#include <list>
1515
#include <variant>
1616

@@ -35,7 +35,7 @@ class ProgramTree {
3535
std::list<common::Reference<const parser::GenericSpec>>;
3636

3737
// Build the ProgramTree rooted at one of these program units.
38-
static ProgramTree Build(const parser::ProgramUnit &, SemanticsContext &);
38+
static ProgramTree &Build(const parser::ProgramUnit &, SemanticsContext &);
3939
static std::optional<ProgramTree> Build(
4040
const parser::MainProgram &, SemanticsContext &);
4141
static std::optional<ProgramTree> Build(

flang/include/flang/Semantics/semantics.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef FORTRAN_SEMANTICS_SEMANTICS_H_
1010
#define FORTRAN_SEMANTICS_SEMANTICS_H_
1111

12+
#include "module-dependences.h"
13+
#include "program-tree.h"
1214
#include "scope.h"
1315
#include "symbol.h"
1416
#include "flang/Common/Fortran-features.h"
@@ -17,7 +19,6 @@
1719
#include "flang/Evaluate/intrinsics.h"
1820
#include "flang/Evaluate/target.h"
1921
#include "flang/Parser/message.h"
20-
#include "flang/Semantics/module-dependences.h"
2122
#include <iosfwd>
2223
#include <set>
2324
#include <string>
@@ -280,6 +281,9 @@ class SemanticsContext {
280281

281282
void DumpSymbols(llvm::raw_ostream &);
282283

284+
// Top-level ProgramTrees are owned by the SemanticsContext for persistence.
285+
ProgramTree &SaveProgramTree(ProgramTree &&);
286+
283287
private:
284288
struct ScopeIndexComparator {
285289
bool operator()(parser::CharBlock, parser::CharBlock) const;
@@ -331,6 +335,7 @@ class SemanticsContext {
331335
ModuleDependences moduleDependences_;
332336
std::map<const Symbol *, SourceName> moduleFileOutputRenamings_;
333337
UnorderedSymbolSet isDefined_;
338+
std::list<ProgramTree> programTrees_;
334339
};
335340

336341
class Semantics {

flang/lib/Semantics/program-tree.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "program-tree.h"
9+
#include "flang/Semantics/program-tree.h"
1010
#include "flang/Common/idioms.h"
1111
#include "flang/Parser/char-block.h"
1212
#include "flang/Semantics/scope.h"
@@ -130,13 +130,13 @@ static ProgramTree BuildModuleTree(
130130
return node;
131131
}
132132

133-
ProgramTree ProgramTree::Build(
133+
ProgramTree &ProgramTree::Build(
134134
const parser::ProgramUnit &x, SemanticsContext &context) {
135135
return common::visit(
136-
[&](const auto &y) {
136+
[&](const auto &y) -> ProgramTree & {
137137
auto node{Build(y.value(), context)};
138138
CHECK(node.has_value());
139-
return std::move(*node);
139+
return context.SaveProgramTree(std::move(*node));
140140
},
141141
x.u);
142142
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "definable.h"
1111
#include "mod-file.h"
1212
#include "pointer-assignment.h"
13-
#include "program-tree.h"
1413
#include "resolve-directives.h"
1514
#include "resolve-names-utils.h"
1615
#include "rewrite-parse-tree.h"
@@ -32,6 +31,7 @@
3231
#include "flang/Parser/tools.h"
3332
#include "flang/Semantics/attr.h"
3433
#include "flang/Semantics/expression.h"
34+
#include "flang/Semantics/program-tree.h"
3535
#include "flang/Semantics/scope.h"
3636
#include "flang/Semantics/semantics.h"
3737
#include "flang/Semantics/symbol.h"
@@ -2490,6 +2490,7 @@ Symbol &ScopeHandler::CopySymbol(const SourceName &name, const Symbol &symbol) {
24902490
}
24912491

24922492
// Look for name only in scope, not in enclosing scopes.
2493+
24932494
Symbol *ScopeHandler::FindInScope(
24942495
const Scope &scope, const parser::Name &name) {
24952496
return Resolve(name, FindInScope(scope, name.source));
@@ -9120,7 +9121,7 @@ bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) {
91209121
ResolveAccParts(context(), x, &topScope_);
91219122
return false;
91229123
}
9123-
auto root{ProgramTree::Build(x, context())};
9124+
ProgramTree &root{ProgramTree::Build(x, context())};
91249125
SetScope(topScope_);
91259126
ResolveSpecificationParts(root);
91269127
FinishSpecificationParts(root);

flang/lib/Semantics/semantics.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,10 @@ void SemanticsContext::DumpSymbols(llvm::raw_ostream &os) {
663663
DoDumpSymbols(os, globalScope());
664664
}
665665

666+
ProgramTree &SemanticsContext::SaveProgramTree(ProgramTree &&tree) {
667+
return programTrees_.emplace_back(std::move(tree));
668+
}
669+
666670
void Semantics::DumpSymbols(llvm::raw_ostream &os) { context_.DumpSymbols(os); }
667671

668672
void Semantics::DumpSymbolsSources(llvm::raw_ostream &os) const {

0 commit comments

Comments
 (0)