Skip to content

Commit 75dc64b

Browse files
committed
Only do deferred init for function local objects, closes #59
Extend declaration parsing to track parent decls/scopes And require a non-local object to have an initializer
1 parent 3df57d4 commit 75dc64b

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

source/cppfront.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2598,7 +2598,16 @@ class cppfront
25982598
else {
25992599
// If there isn't an initializer, use cpp2::deferred_init<T>
26002600
if (!n.initializer) {
2601-
printer.print_cpp2( "cpp2::deferred_init<", n.position() );
2601+
if (n.parent_scope && n.parent_scope->is(declaration_node::function)) {
2602+
printer.print_cpp2( "cpp2::deferred_init<", n.position() );
2603+
}
2604+
else {
2605+
errors.emplace_back(
2606+
n.position(),
2607+
"a non-local object must have an initializer"
2608+
);
2609+
return;
2610+
}
26022611
}
26032612
printer.preempt_position(n.position());
26042613
emit( *type );

source/parse.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,10 @@ struct declaration_node
912912
std::unique_ptr<statement_node> initializer;
913913
capture_group captures;
914914

915+
declaration_node* parent_scope = nullptr;
916+
917+
declaration_node(declaration_node* parent) : parent_scope{parent} { }
918+
915919
// Shorthand for common query
916920
//
917921
auto is(active a) const
@@ -1171,6 +1175,23 @@ class parser
11711175
}
11721176
};
11731177

1178+
// Keep a stack of currently active declarations (still being parsed)
1179+
std::vector<declaration_node*> current_declarations = { nullptr };
1180+
1181+
struct current_declarations_stack_guard {
1182+
parser* pars;
1183+
current_declarations_stack_guard(parser* p, declaration_node* decl)
1184+
: pars{p}
1185+
{
1186+
assert(p);
1187+
assert(decl);
1188+
pars->current_declarations.push_back(decl);
1189+
}
1190+
~current_declarations_stack_guard() {
1191+
pars->current_declarations.pop_back();
1192+
}
1193+
};
1194+
11741195
// Used only for the duration of each parse() call
11751196
std::vector<token> const* tokens_ = nullptr;
11761197
int pos = 0;
@@ -2856,14 +2877,16 @@ class parser
28562877
}
28572878
next();
28582879

2859-
auto n = std::make_unique<declaration_node>();
2880+
auto n = std::make_unique<declaration_node>( current_declarations.back() );
28602881
n->pos = start;
28612882
auto guard =
28622883
captures_allowed
28632884
? make_unique<capture_groups_stack_guard>(this, &n->captures)
28642885
: std::unique_ptr<capture_groups_stack_guard>()
28652886
;
28662887

2888+
auto guard2 = current_declarations_stack_guard(this, n.get());
2889+
28672890
// Next is an an optional type
28682891

28692892
// It could be a function type, declaring a function

source/sema.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ class sema
319319
o << "*** " << sym.identifier->position().to_string()
320320
<< " DEFINITE LAST "
321321
<< (use->is_forward ? "FORWARDING" : "POTENTIALLY MOVING")
322-
<< "USE OF ";
322+
<< " USE OF ";
323323
}
324324

325325
if (is_definite_initialization(sym.identifier)) {
@@ -372,7 +372,7 @@ class sema
372372
// Helpers for readability
373373

374374
// It's an uninitialized variable (incl. named return values) if it's
375-
// a variable with no initializer and that isn't a parameter
375+
// a local variable with no initializer and that isn't a parameter
376376
//
377377
auto is_uninitialized_variable_decl = [&](symbol const& s)
378378
-> declaration_sym const*
@@ -381,7 +381,13 @@ class sema
381381
assert (sym);
382382
if (sym->start && !sym->initializer && !(sym->parameter && sym->parameter->pass != passing_style::out)) {
383383
assert (sym->declaration->is(declaration_node::active::object));
384-
return sym;
384+
// Must be in function scope
385+
if (sym->declaration->parent_scope && sym->declaration->parent_scope->is(declaration_node::function)) {
386+
return sym;
387+
}
388+
else {
389+
return {};
390+
}
385391
}
386392
}
387393
return {};
@@ -401,7 +407,13 @@ class sema
401407
)
402408
)
403409
{
404-
return sym;
410+
// Must be in function scope
411+
if (sym->declaration->parent_scope && sym->declaration->parent_scope->is(declaration_node::function)) {
412+
return sym;
413+
}
414+
else {
415+
return {};
416+
}
405417
}
406418
}
407419
return {};

0 commit comments

Comments
 (0)