Skip to content

Commit 070b75c

Browse files
committed
Fixed two bugs that caused extra .value() emission, closes #29
First, local variable name lookup should stay within the current function and not find any locals not in a directly nested scope Second, we shouldn't be adding `.value()` to names of non-locals (such as the names of members being accessed) Added regression test
1 parent a0d13e1 commit 070b75c

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
vals: () -> (i : int) = {
2+
i = 42;
3+
return;
4+
}
5+
6+
main: () -> int = {
7+
v := vals();
8+
v.i;
9+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// ----- Cpp2 support -----
2+
#define CPP2_USE_MODULES Yes
3+
#include "cpp2util.h"
4+
5+
6+
#line 1 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2"
7+
struct vals__ret {
8+
int i;
9+
};
10+
#line 2 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2"
11+
[[nodiscard]] auto vals() -> vals__ret;
12+
#line 6 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2"
13+
[[nodiscard]] auto main() -> int;
14+
15+
//=== Cpp2 definitions ==========================================================
16+
17+
#line 1 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2"
18+
[[nodiscard]] auto vals() -> vals__ret{
19+
cpp2::deferred_init<int> i;
20+
#line 2 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2"
21+
i.construct(42);
22+
return { std::move(i.value()) };
23+
}
24+
25+
[[nodiscard]] auto main() -> int{
26+
auto v { vals() };
27+
v.i;
28+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-bugfix-for-name-lookup-and-value-decoration.cpp2... ok (all Cpp2, passes safety checks)
2+

source/cppfront.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,12 @@ class cppfront
10071007

10081008
//-----------------------------------------------------------------------
10091009
//
1010-
auto emit(unqualified_id_node const& n, bool in_synthesized_multi_return = false ) -> void
1010+
auto emit(
1011+
unqualified_id_node const& n,
1012+
bool in_synthesized_multi_return = false,
1013+
bool is_local_name = true
1014+
)
1015+
-> void
10111016
{
10121017
auto last_use = is_definite_last_use(n.identifier);
10131018

@@ -1053,6 +1058,7 @@ class cppfront
10531058
}
10541059
else if (!in_definite_init && !in_parameter_list) {
10551060
if (auto decl = sema.get_declaration_of(*n.identifier);
1061+
is_local_name &&
10561062
decl &&
10571063
// note pointer equality: if we're not in the actual declaration of n.identifier
10581064
decl->identifier != n.identifier &&
@@ -1104,10 +1110,10 @@ class cppfront
11041110

11051111
//-----------------------------------------------------------------------
11061112
//
1107-
auto emit(id_expression_node const& n) -> void
1113+
auto emit(id_expression_node const& n, bool is_local_name = true) -> void
11081114
{
11091115
try_emit<id_expression_node::qualified >(n.id);
1110-
try_emit<id_expression_node::unqualified>(n.id);
1116+
try_emit<id_expression_node::unqualified>(n.id, false, is_local_name);
11111117
}
11121118

11131119

@@ -1730,7 +1736,7 @@ class cppfront
17301736
if (i->id_expr) {
17311737
auto print = std::string{};
17321738
printer.emit_to_string(&print);
1733-
emit(*i->id_expr);
1739+
emit(*i->id_expr, false /*not a local name*/);
17341740
printer.emit_to_string();
17351741
suffix.emplace_back( print, i->id_expr->position() );
17361742
}

source/sema.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,23 @@ class sema
244244

245245
// Then look backward to find the first declaration of
246246
// this name that is not deeper (in a nested scope)
247-
for ( ; i != symbols.cbegin(); --i ) {
248-
if (i->sym.index() == symbol::active::declaration && i->depth <= depth) {
247+
for ( ; i != symbols.cbegin(); --i )
248+
{
249+
if (i->sym.index() == symbol::active::declaration && i->depth <= depth)
250+
{
249251
auto const& decl = std::get<symbol::active::declaration>(i->sym);
252+
253+
// Don't look beyond the current function
254+
assert(decl.declaration);
255+
if (decl.declaration->type.index() == declaration_node::function) {
256+
return nullptr;
257+
}
258+
259+
// If the name matches, this is it
250260
if (decl.identifier && *decl.identifier == t) {
251261
return &decl;
252262
}
263+
depth = i->depth;
253264
}
254265
}
255266

0 commit comments

Comments
 (0)