From 6d862919acf0b4f493232a4f488b70a07f375361 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 10 Apr 2023 16:38:00 -0500 Subject: [PATCH 1/3] 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. --- .../tests/generated/wrap_static_fns.c | 1 + .../expectations/tests/wrap-static-fns.rs | 4 +++ bindgen-tests/tests/headers/wrap-static-fns.h | 4 +++ bindgen/codegen/serialize.rs | 25 ++++++++++++++++--- bindgen/ir/ty.rs | 4 +++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c index abc5224229..8d6e97aad1 100644 --- a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c +++ b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c @@ -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(); } diff --git a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs index 0db78054ac..2800d7034d 100644 --- a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs +++ b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs @@ -56,3 +56,7 @@ extern "C" { #[link_name = "takes_enum__extern"] pub fn takes_enum(f: foo) -> foo; } +extern "C" { + #[link_name = "nevermore__extern"] + pub fn nevermore(); +} diff --git a/bindgen-tests/tests/headers/wrap-static-fns.h b/bindgen-tests/tests/headers/wrap-static-fns.h index faa7b7f1ad..4a1862b050 100644 --- a/bindgen-tests/tests/headers/wrap-static-fns.h +++ b/bindgen-tests/tests/headers/wrap-static-fns.h @@ -40,3 +40,7 @@ enum foo { static inline enum foo takes_enum(const enum foo f) { return f; } + +static inline void nevermore() { + while (1) { } +} diff --git a/bindgen/codegen/serialize.rs b/bindgen/codegen/serialize.rs index ac6202356e..ea724354c9 100644 --- a/bindgen/codegen/serialize.rs +++ b/bindgen/codegen/serialize.rs @@ -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) })?; diff --git a/bindgen/ir/ty.rs b/bindgen/ir/ty.rs index 8c505aa49f..572d7de451 100644 --- a/bindgen/ir/ty.rs +++ b/bindgen/ir/ty.rs @@ -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!( From 5a3f7403bffbd36580235d7bc463e6fadb05af97 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 10 Apr 2023 16:43:23 -0500 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aea2e321cc..bbd4f198e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 From c35fdb45c15d532d277dbfd3d4a26e0f84795826 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 10 Apr 2023 16:46:34 -0500 Subject: [PATCH 3/3] Run rustfmt --- bindgen/codegen/serialize.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindgen/codegen/serialize.rs b/bindgen/codegen/serialize.rs index ea724354c9..0baa70a899 100644 --- a/bindgen/codegen/serialize.rs +++ b/bindgen/codegen/serialize.rs @@ -118,7 +118,7 @@ impl<'a> CSerialize<'a> for Function { // Write `wrap_name(args`. write!(writer, " {}(", wrap_name)?; serialize_args(&args, ctx, writer)?; - + // Write `) { name(` if the function returns void and `) { return name(` if it does not. if ret_ty.is_void() { write!(writer, ") {{ {}(", name)?;