Skip to content

Commit a24a143

Browse files
bors[bot]lrh2000
andauthored
Merge #390
390: Clean up the compilation of block expressions r=philberty a=lrh2000 The original implementation of compiling block expressions and function bodies is incorrect. Here is an example. ```rust fn foo() -> i32 { 1; 2; 0 } ``` The above Rust code will compile into the below GIMPLE code. ```c i32 foo () { i32 D.199; D.199 = 1; return D.199; D.199 = 2; return D.199; D.199 = 0; return D.199; } ``` It is obviously incorrect. *(Original in #364 Co-authored-by: lrh2000 <[email protected]>
2 parents e5aedbb + e57b689 commit a24a143

File tree

3 files changed

+36
-46
lines changed

3 files changed

+36
-46
lines changed

gcc/rust/backend/rust-compile.cc

+23-46
Original file line numberDiff line numberDiff line change
@@ -234,32 +234,19 @@ CompileBlock::visit (HIR::BlockExpr &expr)
234234
for (auto &s : expr.get_statements ())
235235
{
236236
auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
237-
if (compiled_expr == nullptr)
238-
continue;
239-
240-
if (result == nullptr)
237+
if (compiled_expr != nullptr)
241238
{
242-
Bstatement *final_stmt
239+
Bstatement *compiled_stmt
243240
= ctx->get_backend ()->expression_statement (fnctx.fndecl,
244241
compiled_expr);
245-
ctx->add_statement (final_stmt);
246-
}
247-
else
248-
{
249-
Bexpression *result_reference
250-
= ctx->get_backend ()->var_expression (result,
251-
s->get_locus_slow ());
252-
253-
Bstatement *assignment = ctx->get_backend ()->assignment_statement (
254-
fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
255-
ctx->add_statement (assignment);
242+
ctx->add_statement (compiled_stmt);
256243
}
257244
}
258245

259246
if (expr.has_expr ())
260247
{
261-
// the previous passes will ensure this is a valid return
262-
// dead code elimination should remove any bad trailing expressions
248+
// the previous passes will ensure this is a valid return or
249+
// a valid trailing expression
263250
Bexpression *compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
264251
if (compiled_expr != nullptr)
265252
{
@@ -388,16 +375,31 @@ HIRCompileBase::compile_function_body (
388375
for (auto &s : function_body->get_statements ())
389376
{
390377
auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
378+
if (compiled_expr != nullptr)
379+
{
380+
Bstatement *compiled_stmt
381+
= ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
382+
ctx->add_statement (compiled_stmt);
383+
}
384+
}
385+
386+
if (function_body->has_expr ())
387+
{
388+
// the previous passes will ensure this is a valid return
389+
// or a valid trailing expression
390+
Bexpression *compiled_expr
391+
= CompileExpr::Compile (function_body->expr.get (), ctx);
392+
391393
if (compiled_expr != nullptr)
392394
{
393395
if (has_return_type)
394396
{
395397
std::vector<Bexpression *> retstmts;
396398
retstmts.push_back (compiled_expr);
397399

398-
auto ret
399-
= ctx->get_backend ()->return_statement (fndecl, retstmts,
400-
s->get_locus_slow ());
400+
auto ret = ctx->get_backend ()->return_statement (
401+
fndecl, retstmts,
402+
function_body->get_final_expr ()->get_locus_slow ());
401403
ctx->add_statement (ret);
402404
}
403405
else
@@ -409,31 +411,6 @@ HIRCompileBase::compile_function_body (
409411
}
410412
}
411413
}
412-
413-
if (function_body->has_expr ())
414-
{
415-
// the previous passes will ensure this is a valid return
416-
// dead code elimination should remove any bad trailing expressions
417-
Bexpression *compiled_expr
418-
= CompileExpr::Compile (function_body->expr.get (), ctx);
419-
420-
if (has_return_type && compiled_expr)
421-
{
422-
std::vector<Bexpression *> retstmts;
423-
retstmts.push_back (compiled_expr);
424-
425-
auto ret = ctx->get_backend ()->return_statement (
426-
fndecl, retstmts,
427-
function_body->get_final_expr ()->get_locus_slow ());
428-
ctx->add_statement (ret);
429-
}
430-
else if (compiled_expr)
431-
{
432-
Bstatement *final_stmt
433-
= ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
434-
ctx->add_statement (final_stmt);
435-
}
436-
}
437414
}
438415

439416
} // namespace Compile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() -> i32 {
2+
let ret = {
3+
1;
4+
2;
5+
0
6+
};
7+
ret
8+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() -> i32 {
2+
1;
3+
2;
4+
0
5+
}

0 commit comments

Comments
 (0)