Skip to content

Commit 88591bb

Browse files
committed
fix(sema): improve heuristic to only move from last (implicit) this
1 parent f9ec202 commit 88591bb

File tree

3 files changed

+76
-40
lines changed

3 files changed

+76
-40
lines changed

regression-tests/pure2-last-use.cpp2

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,21 @@ issue_857: type = {
5858
a: std::unique_ptr<int>;
5959
b: std::unique_ptr<int>;
6060
operator=: (out this, move that) = { }
61-
operator=: (move this) = f_copy(a, this.b);
61+
operator=: (move this) = {
62+
f_inout(a);
63+
f_copy(this.b);
64+
}
6265
f: (move this) = f_copy(this);
6366
f: (move this, move that) = f_copy(this, that);
6467
g: (move this) = f_copy(this.a);
6568
g: (move this, move that) = f_copy(this.a, that.a);
6669
h: (inout this) = f_inout(a);
6770
i: (move this) = f_copy(a);
6871
j: (move this) = f_copy(a);
69-
k: (move this) = f_copy(a, b);
72+
k: (move this) = {
73+
f_inout(a);
74+
f_copy(b);
75+
}
7076
l: (move this) = k();
7177
m: (move this) = this.k();
7278
n: (_) = { }
@@ -85,15 +91,15 @@ issue_857: type = {
8591
f_copy(a);
8692
}
8793
p2: (move this) = {
88-
//f_inout(a); // FIXME Moves `a`.
94+
f_inout(a);
8995
f_copy(this);
9096
}
9197
p3: (move this) = {
9298
//f_inout(this); // FIXME Moves `this`.
9399
f_copy(a);
94100
}
95101
q: (move this) = {
96-
//m(); // FIXME Moves implicit `this`.
102+
h();
97103
n();
98104
}
99105
// FIXME
@@ -171,7 +177,7 @@ draw: () = {
171177
union: type = {
172178
destroy: (inout this) = { }
173179
operator=: (move this) = {
174-
// destroy(); FIXME Discarding `this` still moves it here.
180+
destroy();
175181
_ = this;
176182
}
177183
}

regression-tests/test-results/pure2-last-use.cpp

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@
1212
class issue_857;
1313

1414

15-
#line 117 "pure2-last-use.cpp2"
15+
#line 123 "pure2-last-use.cpp2"
1616
class issue_857_2;
1717

1818

19-
#line 122 "pure2-last-use.cpp2"
19+
#line 128 "pure2-last-use.cpp2"
2020
class issue_857_3;
2121

2222

23-
#line 127 "pure2-last-use.cpp2"
23+
#line 133 "pure2-last-use.cpp2"
2424
class issue_869;
2525

2626

27-
#line 171 "pure2-last-use.cpp2"
27+
#line 177 "pure2-last-use.cpp2"
2828
class cpp2_union;
2929

3030

31-
#line 179 "pure2-last-use.cpp2"
31+
#line 185 "pure2-last-use.cpp2"
3232
class my_string;
3333

3434

@@ -71,6 +71,8 @@ class issue_857 {
7171
#line 60 "pure2-last-use.cpp2"
7272
public: auto operator=(issue_857&& that) noexcept -> issue_857& ;
7373
public: ~issue_857() noexcept;
74+
75+
#line 65 "pure2-last-use.cpp2"
7476
public: auto f() && -> void;
7577
public: auto f(issue_857&& that) && -> void;
7678
public: auto g() && -> void;
@@ -79,6 +81,8 @@ class issue_857 {
7981
public: auto i() && -> void;
8082
public: auto j() && -> void;
8183
public: auto k() && -> void;
84+
85+
#line 76 "pure2-last-use.cpp2"
8286
public: auto l() && -> void;
8387
public: auto m() && -> void;
8488
public: static auto n([[maybe_unused]] auto const& unnamed_param_1) -> void;
@@ -90,19 +94,19 @@ class issue_857 {
9094
public: auto o4() && -> void;
9195
public: auto p0() && -> void;
9296

93-
#line 83 "pure2-last-use.cpp2"
97+
#line 89 "pure2-last-use.cpp2"
9498
public: auto p1() && -> void;
9599

96-
#line 87 "pure2-last-use.cpp2"
100+
#line 93 "pure2-last-use.cpp2"
97101
public: auto p2() && -> void;
98102

99-
#line 91 "pure2-last-use.cpp2"
103+
#line 97 "pure2-last-use.cpp2"
100104
public: auto p3() && -> void;
101105

102-
#line 95 "pure2-last-use.cpp2"
106+
#line 101 "pure2-last-use.cpp2"
103107
public: auto q() && -> void;
104108

105-
#line 99 "pure2-last-use.cpp2"
109+
#line 105 "pure2-last-use.cpp2"
106110
// FIXME
107111
//z: (move this, move that) = {
108112
///*f */ if true { f_copy(this); }
@@ -146,24 +150,24 @@ public: issue_869(issue_869&& that) noexcept;
146150
public: auto operator=(issue_869 const& that) -> issue_869& ;
147151
public: auto operator=(issue_869&& that) noexcept -> issue_869& ;
148152

149-
#line 129 "pure2-last-use.cpp2"
153+
#line 135 "pure2-last-use.cpp2"
150154
};
151155

152156
auto issue_884_3() -> void;
153157

154-
#line 141 "pure2-last-use.cpp2"
158+
#line 147 "pure2-last-use.cpp2"
155159
auto issue_884() -> void;
156160

157-
#line 150 "pure2-last-use.cpp2"
161+
#line 156 "pure2-last-use.cpp2"
158162
auto issue_884_2() -> void;
159163

160-
#line 159 "pure2-last-use.cpp2"
164+
#line 165 "pure2-last-use.cpp2"
161165
auto issue_888(std::string r, int size) -> void;
162166

163-
#line 165 "pure2-last-use.cpp2"
167+
#line 171 "pure2-last-use.cpp2"
164168
auto draw() -> void;
165169

166-
#line 171 "pure2-last-use.cpp2"
170+
#line 177 "pure2-last-use.cpp2"
167171
class cpp2_union {
168172
public: auto destroy() & -> void;
169173
public: ~cpp2_union() noexcept;
@@ -172,7 +176,7 @@ class cpp2_union {
172176
public: auto operator=(cpp2_union const&) -> void = delete;
173177

174178

175-
#line 177 "pure2-last-use.cpp2"
179+
#line 183 "pure2-last-use.cpp2"
176180
};
177181

178182
class my_string {
@@ -252,15 +256,21 @@ auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void{}
252256
b = std::move(that).b;
253257
return *this; }
254258
#line 61 "pure2-last-use.cpp2"
255-
issue_857::~issue_857() noexcept { f_copy(std::move(*this).a, std::move((*this)).b); }
259+
issue_857::~issue_857() noexcept{
260+
f_inout(a);
261+
f_copy(std::move((*this)).b);
262+
}
256263
auto issue_857::f() && -> void { f_copy(std::move((*this))); }
257264
auto issue_857::f(issue_857&& that) && -> void { f_copy(std::move((*this)), std::move(that)); }
258265
auto issue_857::g() && -> void { f_copy(std::move((*this)).a); }
259266
auto issue_857::g(issue_857&& that) && -> void { f_copy(std::move((*this)).a, std::move(that).a); }
260267
auto issue_857::h() & -> void { f_inout(a); }
261268
auto issue_857::i() && -> void { f_copy(std::move(*this).a); }
262269
auto issue_857::j() && -> void { f_copy(std::move(*this).a); }
263-
auto issue_857::k() && -> void { f_copy(std::move(*this).a, std::move(*this).b); }
270+
auto issue_857::k() && -> void{
271+
f_inout(a);
272+
f_copy(std::move(*this).b);
273+
}
264274
auto issue_857::l() && -> void { std::move(*this).k(); }
265275
auto issue_857::m() && -> void { CPP2_UFCS(k)(std::move((*this))); }
266276
auto issue_857::n([[maybe_unused]] auto const& unnamed_param_1) -> void{}
@@ -269,7 +279,7 @@ auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void{}
269279
auto issue_857::o1() && -> void { CPP2_UFCS(n)(std::move((*this))); }
270280
auto issue_857::o2() && -> void { CPP2_UFCS(n)(0); }
271281
auto issue_857::o3() && -> void { std::move(*this).n(0); }
272-
auto issue_857::o4() && -> void { std::move(*this).n(std::move((*this))); }
282+
auto issue_857::o4() && -> void { n(std::move((*this))); }
273283
auto issue_857::p0() && -> void{
274284
f_inout(a);
275285
f_copy(std::move((*this)).a);
@@ -279,22 +289,22 @@ auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void{}
279289
f_copy(std::move(*this).a);
280290
}
281291
auto issue_857::p2() && -> void{
282-
//f_inout(a); // FIXME Moves `a`.
292+
f_inout(a);
283293
f_copy(std::move((*this)));
284294
}
285295
auto issue_857::p3() && -> void{
286296
//f_inout(this); // FIXME Moves `this`.
287297
f_copy(std::move(*this).a);
288298
}
289299
auto issue_857::q() && -> void{
290-
//m(); // FIXME Moves implicit `this`.
300+
h();
291301
std::move(*this).n();
292302
}
293303

294-
#line 121 "pure2-last-use.cpp2"
304+
#line 127 "pure2-last-use.cpp2"
295305
int gi {0};
296306

297-
#line 124 "pure2-last-use.cpp2"
307+
#line 130 "pure2-last-use.cpp2"
298308
auto issue_857_3::f() && -> void { static_cast<void>(f_inout(std::move(*this).i)); }
299309

300310

@@ -335,7 +345,7 @@ issue_869::issue_869(issue_869 const& that)
335345
if (CPP2_UFCS(is_i)(std::move(that))) {set_i(CPP2_UFCS(i)(std::move(that)));}
336346
return *this;
337347
}
338-
#line 131 "pure2-last-use.cpp2"
348+
#line 137 "pure2-last-use.cpp2"
339349
auto issue_884_3() -> void{
340350
auto x {cpp2_new<int>(0)};
341351
if (true) {}
@@ -376,17 +386,17 @@ auto draw() -> void{
376386
static_cast<void>(CPP2_UFCS_MOVE(vertex)((std::move(pos))));
377387
}
378388

379-
#line 172 "pure2-last-use.cpp2"
389+
#line 178 "pure2-last-use.cpp2"
380390
auto cpp2_union::destroy() & -> void{}
381391
cpp2_union::~cpp2_union() noexcept{
382-
// destroy(); FIXME Discarding `this` still moves it here.
392+
destroy();
383393
static_cast<void>(std::move((*this)));
384394
}
385395

386-
#line 184 "pure2-last-use.cpp2"
396+
#line 190 "pure2-last-use.cpp2"
387397
auto main(int const argc_, char** argv_) -> int{
388398
auto const args = cpp2::make_args(argc_, argv_);
389-
#line 185 "pure2-last-use.cpp2"
399+
#line 191 "pure2-last-use.cpp2"
390400
issue_683(args);
391401
issue_847_2(std::vector<std::unique_ptr<int>>());
392402
}

source/sema.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,21 +343,22 @@ class sema
343343
//
344344
auto get_declaration_of(
345345
token const* t,
346-
bool look_beyond_current_function = false
347-
)
346+
bool look_beyond_current_function = false,
347+
bool look_up_to_type = false
348+
) const
348349
-> declaration_sym const*
349350
{
350351
if (!t) {
351352
return {};
352353
}
353-
return get_declaration_of(*t, look_beyond_current_function);
354+
return get_declaration_of(*t, look_beyond_current_function, look_up_to_type);
354355
}
355356

356357
auto get_declaration_of(
357358
token const& t,
358359
bool look_beyond_current_function = false,
359360
bool look_up_to_type = false
360-
)
361+
) const
361362
-> declaration_sym const*
362363
{
363364
// First find the position the query is coming from
@@ -367,7 +368,13 @@ class sema
367368
i != symbols.cend()
368369
&& (
369370
!i->get_token()
370-
|| final_position[i->get_token()] < final_position[&t]
371+
|| [&]() {
372+
auto lhs = final_position.find(i->get_token());
373+
auto rhs = final_position.find(&t);
374+
return lhs == final_position.end()
375+
|| rhs == final_position.end()
376+
|| lhs->second < rhs->second;
377+
}()
371378
)
372379
)
373380
{
@@ -756,7 +763,20 @@ class sema
756763
assert (sym.identifier);
757764

758765
// If we find a use of this identifier
759-
if (*sym.identifier == *id)
766+
if (
767+
*sym.identifier == *id
768+
|| (
769+
in_type_scope
770+
&& (
771+
*sym.identifier == "this"
772+
|| [&]() {
773+
auto decl = get_declaration_of(sym.get_token(), true, true);
774+
return decl
775+
&& decl->declaration->parent_is_type();
776+
}()
777+
)
778+
)
779+
)
760780
{
761781
if (
762782
!found

0 commit comments

Comments
 (0)