Skip to content

Commit

Permalink
Do not return when calling void functions (#2497)
Browse files Browse the repository at this point in the history
* Do not return when calling `void` functions

Update the code generation for the `--wrap-static-fns` feature so the
wrapper for a static function that returns `void` no longer contains a
`return` statement and only calls the function instead.
  • Loading branch information
pvdrz authored Apr 10, 2023
1 parent 7d24305 commit a968109
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@
## Added

## Changed
* Wrappers for static functions that return `void` no longer contain a `return`
statement and only call the static function instead.

## Removed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ int takes_fn__extern(int (f) (int)) { return takes_fn(f); }
int takes_alias__extern(func f) { return takes_alias(f); }
int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); }
enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); }
void nevermore__extern(void) { nevermore(); }
4 changes: 4 additions & 0 deletions bindgen-tests/tests/expectations/tests/wrap-static-fns.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions bindgen-tests/tests/headers/wrap-static-fns.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@ enum foo {
static inline enum foo takes_enum(const enum foo f) {
return f;
}

static inline void nevermore() {
while (1) { }
}
25 changes: 21 additions & 4 deletions bindgen/codegen/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,31 @@ impl<'a> CSerialize<'a> for Function {

// The name used for the wrapper self.
let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix());

// The function's return type
let ret_ty = signature.return_type();
let ret_ty = {
let type_id = signature.return_type();
let item = ctx.resolve_item(type_id);
let ret_ty = item.expect_type();

// Write `ret_ty`.
ret_ty.serialize(ctx, item, stack, writer)?;

ret_ty
};

// Write `ret_ty wrap_name(args) { return name(arg_names)' }`
ret_ty.serialize(ctx, (), stack, writer)?;
// Write `wrap_name(args`.
write!(writer, " {}(", wrap_name)?;
serialize_args(&args, ctx, writer)?;
write!(writer, ") {{ return {}(", name)?;

// Write `) { name(` if the function returns void and `) { return name(` if it does not.
if ret_ty.is_void() {
write!(writer, ") {{ {}(", name)?;
} else {
write!(writer, ") {{ return {}(", name)?;
}

// Write `arg_names); }`.
serialize_sep(", ", args.iter(), ctx, writer, |(name, _), _, buf| {
write!(buf, "{}", name).map_err(From::from)
})?;
Expand Down
4 changes: 4 additions & 0 deletions bindgen/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ impl Type {
matches!(self.kind, TypeKind::Enum(..))
}

/// Is this void?
pub(crate) fn is_void(&self) -> bool {
matches!(self.kind, TypeKind::Void)
}
/// Is this either a builtin or named type?
pub(crate) fn is_builtin_or_type_param(&self) -> bool {
matches!(
Expand Down

0 comments on commit a968109

Please sign in to comment.