Skip to content

Commit 52f4bd8

Browse files
committed
transpile: Strip tail return only when transpiling a function
1 parent 87faf6a commit 52f4bd8

File tree

4 files changed

+34
-31
lines changed

4 files changed

+34
-31
lines changed

c2rust-transpile/src/cfg/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ pub enum ImplicitReturnType {
558558
///
559559
/// TODO: document
560560
StmtExpr(ExprContext, CExprId, Label),
561+
562+
StmtExprVoid,
561563
}
562564

563565
/// A complete control-flow graph
@@ -632,6 +634,7 @@ impl Cfg<Label, StmtOrDecl> {
632634
mk().break_expr_value(Some(brk_label.pretty_print()), Some(val)),
633635
)));
634636
}
637+
ImplicitReturnType::StmtExprVoid => (),
635638
};
636639

637640
cfg_builder.add_wip_block(wip, End);
@@ -2114,13 +2117,8 @@ impl CfgBuilder {
21142117
};
21152118

21162119
// Run relooper
2117-
let mut stmts = translator.convert_cfg(
2118-
&format!("<substmt_{:?}>", stmt_id),
2119-
graph,
2120-
store,
2121-
live_in,
2122-
false,
2123-
)?;
2120+
let mut stmts =
2121+
translator.convert_cfg(&format!("<substmt_{:?}>", stmt_id), graph, store, live_in)?;
21242122

21252123
let inner_span = stmts.first().map(|stmt| stmt.span());
21262124

c2rust-transpile/src/cfg/structures.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use super::*;
44
use log::warn;
5-
use syn::{spanned::Spanned as _, ExprBreak, ExprIf, ExprReturn, ExprUnary, Stmt};
5+
use syn::{spanned::Spanned as _, ExprBreak, ExprIf, ExprUnary, Stmt};
66

77
use crate::rust_ast::{comment_store, set_span::SetSpan, BytePos, SpanExt};
88

@@ -12,7 +12,6 @@ pub fn structured_cfg(
1212
comment_store: &mut comment_store::CommentStore,
1313
current_block: Box<Expr>,
1414
debug_labels: bool,
15-
cut_out_trailing_ret: bool,
1615
) -> TranslationResult<Vec<Stmt>> {
1716
let ast: StructuredAST<Box<Expr>, Pat, Label, Stmt> =
1817
structured_cfg_help(vec![], &IndexSet::new(), root, &mut IndexSet::new())?;
@@ -21,15 +20,7 @@ pub fn structured_cfg(
2120
debug_labels,
2221
current_block,
2322
};
24-
let (mut stmts, _span) = s.to_stmt(ast, comment_store);
25-
26-
// If the very last statement in the vector is a `return`, we can either cut it out or replace
27-
// it with the returned value.
28-
if cut_out_trailing_ret {
29-
if let Some(Stmt::Expr(Expr::Return(ExprReturn { expr: None, .. }), _)) = stmts.last() {
30-
stmts.pop();
31-
}
32-
}
23+
let (stmts, _span) = s.to_stmt(ast, comment_store);
3324

3425
Ok(stmts)
3526
}

c2rust-transpile/src/translator/mod.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ use proc_macro2::{Punct, Spacing::*, Span, TokenStream, TokenTree};
1515
use syn::spanned::Spanned as _;
1616
use syn::{
1717
AttrStyle, BareVariadic, Block, Expr, ExprBinary, ExprBlock, ExprBreak, ExprCast, ExprField,
18-
ExprIndex, ExprParen, ExprUnary, FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro,
19-
ForeignItemStatic, ForeignItemType, Ident, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
20-
ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait,
21-
ItemTraitAlias, ItemType, ItemUnion, ItemUse, Lit, MacroDelimiter, PathSegment, ReturnType,
22-
Stmt, Type, TypeTuple, UseTree, Visibility,
18+
ExprIndex, ExprParen, ExprReturn, ExprUnary, FnArg, ForeignItem, ForeignItemFn,
19+
ForeignItemMacro, ForeignItemStatic, ForeignItemType, Ident, Item, ItemConst, ItemEnum,
20+
ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct,
21+
ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Lit, MacroDelimiter, PathSegment,
22+
ReturnType, Stmt, Type, TypeTuple, UseTree, Visibility,
2323
};
2424
use syn::{BinOp, UnOp}; // To override `c_ast::{BinOp,UnOp}` from glob import.
2525

@@ -2500,7 +2500,8 @@ impl<'c> Translation<'c> {
25002500
_ => panic!("function body expects to be a compound statement"),
25012501
};
25022502
let mut converted_body =
2503-
self.convert_function_body(ctx, name, body_ids, return_type, ret)?;
2503+
self.convert_block_with_scope(ctx, name, body_ids, return_type, ret)?;
2504+
strip_tail_return(&mut converted_body);
25042505

25052506
// If `alloca` was used in the function body, include a variable to hold the
25062507
// allocations.
@@ -2617,7 +2618,6 @@ impl<'c> Translation<'c> {
26172618
graph: cfg::Cfg<cfg::Label, cfg::StmtOrDecl>,
26182619
store: cfg::DeclStmtStore,
26192620
live_in: IndexSet<CDeclId>,
2620-
cut_out_trailing_ret: bool,
26212621
) -> TranslationResult<Vec<Stmt>> {
26222622
if self.tcfg.dump_function_cfgs {
26232623
graph
@@ -2679,12 +2679,11 @@ impl<'c> Translation<'c> {
26792679
&mut self.comment_store.borrow_mut(),
26802680
current_block,
26812681
self.tcfg.debug_relooper_labels,
2682-
cut_out_trailing_ret,
26832682
)?);
26842683
Ok(stmts)
26852684
}
26862685

2687-
fn convert_function_body(
2686+
fn convert_block_with_scope(
26882687
&self,
26892688
ctx: ExprContext,
26902689
name: &str,
@@ -2695,7 +2694,7 @@ impl<'c> Translation<'c> {
26952694
// Function body scope
26962695
self.with_scope(|| {
26972696
let (graph, store) = cfg::Cfg::from_stmts(self, ctx, body_ids, ret, ret_ty)?;
2698-
self.convert_cfg(name, graph, store, IndexSet::new(), true)
2697+
self.convert_cfg(name, graph, store, IndexSet::new())
26992698
})
27002699
}
27012700

@@ -4359,15 +4358,21 @@ impl<'c> Translation<'c> {
43594358
let mut stmts = match self.ast_context[result_id].kind {
43604359
CStmtKind::Expr(expr_id) => {
43614360
let ret = cfg::ImplicitReturnType::StmtExpr(ctx, expr_id, lbl.clone());
4362-
self.convert_function_body(ctx, &name, &substmt_ids[0..(n - 1)], None, ret)?
4361+
self.convert_block_with_scope(
4362+
ctx,
4363+
&name,
4364+
&substmt_ids[0..(n - 1)],
4365+
None,
4366+
ret,
4367+
)?
43634368
}
43644369

4365-
_ => self.convert_function_body(
4370+
_ => self.convert_block_with_scope(
43664371
ctx,
43674372
&name,
43684373
substmt_ids,
43694374
None,
4370-
cfg::ImplicitReturnType::Void,
4375+
cfg::ImplicitReturnType::StmtExprVoid,
43714376
)?,
43724377
};
43734378

@@ -5379,3 +5384,11 @@ impl<'c> Translation<'c> {
53795384
}
53805385
}
53815386
}
5387+
5388+
// If the very last statement in the vector is a `return`, either cut it out or replace it with
5389+
// the returned value.
5390+
fn strip_tail_return(stmts: &mut Vec<Stmt>) {
5391+
if let Some(Stmt::Expr(Expr::Return(ExprReturn { expr: None, .. }), _)) = stmts.last() {
5392+
stmts.pop();
5393+
}
5394+
}

c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,6 @@ pub unsafe extern "C" fn compound_literal() {
5959
#[no_mangle]
6060
pub unsafe extern "C" fn statement_expr() {
6161
puts(b"should execute\0" as *const u8 as *const ::core::ffi::c_char);
62+
return;
6263
puts(b"should be unreachable!\0" as *const u8 as *const ::core::ffi::c_char);
6364
}

0 commit comments

Comments
 (0)