diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-06 18:18:42 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-08 11:36:54 +0000 |
commit | 4e0189ed288223f8b376eedd286f5bdff5b35698 (patch) | |
tree | 89ab8d6db72bc19028d9ecb3a1946e8c0aa01ebd /gcc/rust/backend/rust-compile.cc | |
parent | 290fc4f416c94a86aa5e3d22b785890a12686972 (diff) | |
download | gcc-4e0189ed288223f8b376eedd286f5bdff5b35698.zip gcc-4e0189ed288223f8b376eedd286f5bdff5b35698.tar.gz gcc-4e0189ed288223f8b376eedd286f5bdff5b35698.tar.bz2 |
Implicit Returns support.
For implict returns we must consider cases with a block having multiple
returns:
HIR::BlockExpr Stmts {
...
return x
}
HIR::BlockExpr final_expression {
x + 1
}
Although the code above is bad this is valid rust code and the rust
compiler correctly identifies the final_expression as unreachable.
This dead code eliminiation is done as part of AST to HIR lowering.
Type resolution examines all blocks to identifiy if they terminate
a function with a return/final expression it must correspond accordngly.
If the block is the final block the resulting termination of the block
must match the return type of the function, else the block must conform
to unit type.
Diffstat (limited to 'gcc/rust/backend/rust-compile.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 24b45ee..a52f183 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -90,6 +90,23 @@ CompileBlock::visit (HIR::BlockExpr &expr) return true; }); + if (expr.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 (expr.expr.get (), ctx); + rust_assert (compiled_expr != nullptr); + + auto fncontext = ctx->peek_fn (); + + std::vector<Bexpression *> retstmts; + retstmts.push_back (compiled_expr); + auto s + = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts, + expr.expr->get_locus_slow ()); + ctx->add_statement (s); + } + ctx->pop_block (); translated = new_block; } |