Skip to content

Commit 5b6e1fd

Browse files
committed
fix(sema): apply sema phase to generated code
1 parent 4d48cc3 commit 5b6e1fd

File tree

5 files changed

+145
-13
lines changed

5 files changed

+145
-13
lines changed

regression-tests/pure2-last-use.cpp2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ issue_857_3: @struct type = {
120120
f: (move this) = _ = f_inout(i);
121121
}
122122

123+
issue_869: @union type = {
124+
i: int;
125+
}
123126

124127
issue_884_3: () = {
125128
x := new<int>(0);

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

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ class issue_857_2;
2020
class issue_857_3;
2121

2222

23-
#line 164 "pure2-last-use.cpp2"
23+
#line 123 "pure2-last-use.cpp2"
24+
class issue_869;
25+
26+
27+
#line 167 "pure2-last-use.cpp2"
2428
class my_string;
2529

2630

@@ -120,22 +124,39 @@ class issue_857_3 {
120124
public: auto f() && -> void;
121125
};
122126

123-
#line 124 "pure2-last-use.cpp2"
127+
class issue_869 {
128+
private: std::aligned_storage_t<cpp2::max(sizeof(int))> _storage {}; private: cpp2::i8 _discriminator {-1}; public: [[nodiscard]] auto is_i() const& -> bool;
129+
public: [[nodiscard]] auto i() const& -> int const&;
130+
public: [[nodiscard]] auto i() & -> int&;
131+
public: auto set_i(cpp2::in<int> _value) & -> void;
132+
public: auto set_i(auto&& ..._args) & -> void;
133+
private: auto _destroy() & -> void;
134+
public: ~issue_869() noexcept;
135+
public: explicit issue_869();
136+
public: issue_869(issue_869 const& that);
137+
138+
public: issue_869(issue_869&& that) noexcept;
139+
public: auto operator=(issue_869 const& that) -> issue_869& ;
140+
public: auto operator=(issue_869&& that) noexcept -> issue_869& ;
141+
142+
#line 125 "pure2-last-use.cpp2"
143+
};
144+
124145
auto issue_884_3() -> void;
125146

126-
#line 134 "pure2-last-use.cpp2"
147+
#line 137 "pure2-last-use.cpp2"
127148
auto issue_884() -> void;
128149

129-
#line 143 "pure2-last-use.cpp2"
150+
#line 146 "pure2-last-use.cpp2"
130151
auto issue_884_2() -> void;
131152

132-
#line 152 "pure2-last-use.cpp2"
153+
#line 155 "pure2-last-use.cpp2"
133154
auto issue_888(std::string r, int size) -> void;
134155

135-
#line 158 "pure2-last-use.cpp2"
156+
#line 161 "pure2-last-use.cpp2"
136157
auto draw() -> void;
137158

138-
#line 164 "pure2-last-use.cpp2"
159+
#line 167 "pure2-last-use.cpp2"
139160
class my_string {
140161
public: std::string string;
141162
public: std::size_t size {CPP2_UFCS(size)(string)};
@@ -254,7 +275,45 @@ int gi {0};
254275
#line 120 "pure2-last-use.cpp2"
255276
auto issue_857_3::f() && -> void { static_cast<void>(f_inout(std::move(*this).i)); }
256277

257-
#line 124 "pure2-last-use.cpp2"
278+
279+
280+
[[nodiscard]] auto issue_869::is_i() const& -> bool { return _discriminator == 0; }
281+
[[nodiscard]] auto issue_869::i() const& -> int const& {
282+
cpp2::Default.expects(is_i(), "");return *cpp2::assert_not_null(reinterpret_cast<int const*>(&_storage)); }
283+
[[nodiscard]] auto issue_869::i() & -> int& {
284+
cpp2::Default.expects(is_i(), "");return *cpp2::assert_not_null(reinterpret_cast<int*>(&_storage)); }
285+
auto issue_869::set_i(cpp2::in<int> _value) & -> void{if (!(is_i())) {_destroy();std::construct_at(reinterpret_cast<int*>(&_storage), _value);}else {*cpp2::assert_not_null(reinterpret_cast<int*>(&_storage)) = _value;}_discriminator = 0;}
286+
auto issue_869::set_i(auto&& ..._args) & -> void{if (!(is_i())) {_destroy();std::construct_at(reinterpret_cast<int*>(&_storage), CPP2_FORWARD(_args)...);}else {*cpp2::assert_not_null(reinterpret_cast<int*>(&_storage)) = int{CPP2_FORWARD(_args)...};}_discriminator = 0;}
287+
auto issue_869::_destroy() & -> void{
288+
if (_discriminator == 0) {std::destroy_at(reinterpret_cast<int*>(&_storage));}
289+
_discriminator = -1;
290+
}
291+
292+
issue_869::~issue_869() noexcept{CPP2_UFCS(_destroy)((*this));static_cast<void>(std::move((*this)));}
293+
issue_869::issue_869(){}
294+
issue_869::issue_869(issue_869 const& that)
295+
: _storage{ }
296+
, _discriminator{ -1 }{
297+
if (CPP2_UFCS(is_i)(that)) {set_i(CPP2_UFCS(i)(that));}
298+
}
299+
300+
301+
issue_869::issue_869(issue_869&& that) noexcept
302+
: _storage{ }
303+
, _discriminator{ -1 }{
304+
if (CPP2_UFCS(is_i)(std::move(that))) {set_i(CPP2_UFCS(i)(std::move(that)));}
305+
}
306+
307+
auto issue_869::operator=(issue_869 const& that) -> issue_869& {
308+
if (CPP2_UFCS(is_i)(that)) {set_i(CPP2_UFCS(i)(that));}
309+
return *this;
310+
}
311+
312+
auto issue_869::operator=(issue_869&& that) noexcept -> issue_869& {
313+
if (CPP2_UFCS(is_i)(std::move(that))) {set_i(CPP2_UFCS(i)(std::move(that)));}
314+
return *this;
315+
}
316+
#line 127 "pure2-last-use.cpp2"
258317
auto issue_884_3() -> void{
259318
auto x {cpp2_new<int>(0)};
260319
if (true) {}
@@ -295,10 +354,10 @@ auto draw() -> void{
295354
static_cast<void>(CPP2_UFCS_MOVE(vertex)((std::move(pos))));
296355
}
297356

298-
#line 169 "pure2-last-use.cpp2"
357+
#line 172 "pure2-last-use.cpp2"
299358
auto main(int const argc_, char** argv_) -> int{
300359
auto const args = cpp2::make_args(argc_, argv_);
301-
#line 170 "pure2-last-use.cpp2"
360+
#line 173 "pure2-last-use.cpp2"
302361
issue_683(args);
303362
issue_847_2(std::vector<std::unique_ptr<int>>());
304363
}

source/reflect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1682,7 +1682,7 @@ std::string destroy = " private _destroy: (inout this) = {\n";
16821682

16831683
// Add the destructor
16841684
#line 1199 "reflect.h2"
1685-
CPP2_UFCS(add_member)(t, " operator=: (move this) = { _destroy(); }");
1685+
CPP2_UFCS(add_member)(t, " operator=: (move this) = { this._destroy(); _ = this; }");
16861686

16871687
// Add default constructor
16881688
CPP2_UFCS(add_member)(t, " operator=: (out this) = { }");

source/reflect.h2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ union: (inout t : meta::type_declaration)
11961196
}
11971197

11981198
// Add the destructor
1199-
t.add_member( " operator=: (move this) = { _destroy(); }" );
1199+
t.add_member( " operator=: (move this) = { this._destroy(); _ = this; }" );
12001200

12011201
// Add default constructor
12021202
t.add_member( " operator=: (out this) = { }" );

source/sema.h

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ struct declaration_sym {
7676
assert (declaration);
7777
return declaration->position();
7878
}
79+
80+
auto get_token() const
81+
-> token const*
82+
{
83+
if (
84+
declaration
85+
&& declaration->identifier
86+
&& declaration->identifier->identifier
87+
)
88+
{
89+
return declaration->identifier->identifier;
90+
}
91+
return nullptr;
92+
}
7993
};
8094

8195
struct identifier_sym {
@@ -96,6 +110,12 @@ struct identifier_sym {
96110
assert (identifier);
97111
return identifier->position();
98112
}
113+
114+
auto get_token() const
115+
-> token const*
116+
{
117+
return identifier;
118+
}
99119
};
100120

101121
struct selection_sym {
@@ -116,6 +136,13 @@ struct selection_sym {
116136
assert (selection);
117137
return selection->position();
118138
}
139+
140+
auto get_token() const
141+
-> token const*
142+
{
143+
assert (selection);
144+
return selection->identifier;
145+
}
119146
};
120147

121148
struct compound_sym {
@@ -139,6 +166,12 @@ struct compound_sym {
139166
assert (compound);
140167
return compound->position();
141168
}
169+
170+
auto get_token() const
171+
-> token const*
172+
{
173+
return nullptr;
174+
}
142175
};
143176

144177
struct symbol {
@@ -189,6 +222,37 @@ struct symbol {
189222
return { 0, 0 };
190223
}
191224
}
225+
226+
auto get_token() const
227+
-> token const*
228+
{
229+
switch (sym.index())
230+
{
231+
break;case declaration: {
232+
auto const& s = std::get<declaration>(sym);
233+
return s.get_token();
234+
}
235+
236+
break;case identifier: {
237+
auto const& s = std::get<identifier>(sym);
238+
return s.get_token();
239+
}
240+
241+
break;case selection: {
242+
auto const& s = std::get<selection>(sym);
243+
return s.get_token();
244+
}
245+
246+
break;case compound: {
247+
auto const& s = std::get<compound>(sym);
248+
return s.get_token();
249+
}
250+
251+
break;default:
252+
assert (!"illegal symbol state");
253+
return nullptr;
254+
}
255+
}
192256
};
193257

194258

@@ -301,7 +365,10 @@ class sema
301365
auto i = symbols.cbegin();
302366
while (
303367
i != symbols.cend()
304-
&& i->position() < t.position()
368+
&& (
369+
!i->get_token()
370+
|| final_position[i->get_token()] < final_position[&t]
371+
)
305372
)
306373
{
307374
++i;
@@ -1672,6 +1739,7 @@ class sema
16721739
bool inside_returns_list = false;
16731740
bool just_entered_for = false;
16741741
parameter_declaration_node const* inside_out_parameter = {};
1742+
std::map<token const*, int> final_position = {};
16751743

16761744
auto start(next_expression_tag const&, int) -> void
16771745
{
@@ -1817,6 +1885,8 @@ class sema
18171885

18181886
auto start(token const& t, int) -> void
18191887
{
1888+
auto fpos = std::ssize(final_position);
1889+
final_position[&t] = cpp2::unsafe_narrow<int>(fpos);
18201890
if (t.type() == lexeme::Dot) {
18211891
started_member_access = true;
18221892
}

0 commit comments

Comments
 (0)