diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-25 17:14:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-25 17:14:16 +0000 |
commit | a24a14371b16c316a815a9440b1d960cd3f885dd (patch) | |
tree | e6ea6bfe5f4ba500144c74c2bc55c2b7fdd3d8c5 /gcc | |
parent | e5aedbbb241220f7ffb89d96a885dd6e44038259 (diff) | |
parent | e57b6895defde89d686620fa865e8edac637c0c5 (diff) | |
download | gcc-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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 69 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/execute/block_expr1.rs | 8 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/execute/func1.rs | 5 |
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 +} |