aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-25 17:14:16 +0000
committerGitHub <noreply@github.com>2021-04-25 17:14:16 +0000
commita24a14371b16c316a815a9440b1d960cd3f885dd (patch)
treee6ea6bfe5f4ba500144c74c2bc55c2b7fdd3d8c5
parente5aedbbb241220f7ffb89d96a885dd6e44038259 (diff)
parente57b6895defde89d686620fa865e8edac637c0c5 (diff)
downloadgcc-a24a14371b16c316a815a9440b1d960cd3f885dd.zip
gcc-a24a14371b16c316a815a9440b1d960cd3f885dd.tar.gz
gcc-a24a14371b16c316a815a9440b1d960cd3f885dd.tar.bz2
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 https://github.com/Rust-GCC/gccrs/pull/364)* Co-authored-by: lrh2000 <lrh2000@pku.edu.cn>
-rw-r--r--gcc/rust/backend/rust-compile.cc69
-rw-r--r--gcc/testsuite/rust.test/execute/block_expr1.rs8
-rw-r--r--gcc/testsuite/rust.test/execute/func1.rs5
3 files changed, 36 insertions, 46 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 9375dd0..4893541 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -234,32 +234,19 @@ CompileBlock::visit (HIR::BlockExpr &expr)
for (auto &s : expr.get_statements ())
{
auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
- if (compiled_expr == nullptr)
- continue;
-
- if (result == nullptr)
+ if (compiled_expr != nullptr)
{
- Bstatement *final_stmt
+ Bstatement *compiled_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl,
compiled_expr);
- ctx->add_statement (final_stmt);
- }
- else
- {
- Bexpression *result_reference
- = ctx->get_backend ()->var_expression (result,
- s->get_locus_slow ());
-
- Bstatement *assignment = ctx->get_backend ()->assignment_statement (
- fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
- ctx->add_statement (assignment);
+ ctx->add_statement (compiled_stmt);
}
}
if (expr.has_expr ())
{
- // the previous passes will ensure this is a valid return
- // dead code elimination should remove any bad trailing expressions
+ // the previous passes will ensure this is a valid return or
+ // a valid trailing expression
Bexpression *compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
if (compiled_expr != nullptr)
{
@@ -390,14 +377,29 @@ HIRCompileBase::compile_function_body (
auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
if (compiled_expr != nullptr)
{
+ Bstatement *compiled_stmt
+ = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
+ ctx->add_statement (compiled_stmt);
+ }
+ }
+
+ if (function_body->has_expr ())
+ {
+ // the previous passes will ensure this is a valid return
+ // or a valid trailing expression
+ Bexpression *compiled_expr
+ = CompileExpr::Compile (function_body->expr.get (), ctx);
+
+ if (compiled_expr != nullptr)
+ {
if (has_return_type)
{
std::vector<Bexpression *> retstmts;
retstmts.push_back (compiled_expr);
- auto ret
- = ctx->get_backend ()->return_statement (fndecl, retstmts,
- s->get_locus_slow ());
+ auto ret = ctx->get_backend ()->return_statement (
+ fndecl, retstmts,
+ function_body->get_final_expr ()->get_locus_slow ());
ctx->add_statement (ret);
}
else
@@ -409,31 +411,6 @@ HIRCompileBase::compile_function_body (
}
}
}
-
- if (function_body->has_expr ())
- {
- // the previous passes will ensure this is a valid return
- // dead code elimination should remove any bad trailing expressions
- Bexpression *compiled_expr
- = CompileExpr::Compile (function_body->expr.get (), ctx);
-
- if (has_return_type && compiled_expr)
- {
- std::vector<Bexpression *> retstmts;
- retstmts.push_back (compiled_expr);
-
- auto ret = ctx->get_backend ()->return_statement (
- fndecl, retstmts,
- function_body->get_final_expr ()->get_locus_slow ());
- ctx->add_statement (ret);
- }
- else if (compiled_expr)
- {
- Bstatement *final_stmt
- = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
- ctx->add_statement (final_stmt);
- }
- }
}
} // namespace Compile
diff --git a/gcc/testsuite/rust.test/execute/block_expr1.rs b/gcc/testsuite/rust.test/execute/block_expr1.rs
new file mode 100644
index 0000000..d561f8c
--- /dev/null
+++ b/gcc/testsuite/rust.test/execute/block_expr1.rs
@@ -0,0 +1,8 @@
+fn main() -> i32 {
+ let ret = {
+ 1;
+ 2;
+ 0
+ };
+ ret
+}
diff --git a/gcc/testsuite/rust.test/execute/func1.rs b/gcc/testsuite/rust.test/execute/func1.rs
new file mode 100644
index 0000000..0a093d8
--- /dev/null
+++ b/gcc/testsuite/rust.test/execute/func1.rs
@@ -0,0 +1,5 @@
+fn main() -> i32 {
+ 1;
+ 2;
+ 0
+}