Skip to content

Commit a968109

Browse files
authored
Do not return when calling void functions (#2497)
* 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.
1 parent 7d24305 commit a968109

File tree

6 files changed

+36
-4
lines changed

6 files changed

+36
-4
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@
167167
## Added
168168

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

171173
## Removed
172174

bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ int takes_fn__extern(int (f) (int)) { return takes_fn(f); }
1010
int takes_alias__extern(func f) { return takes_alias(f); }
1111
int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); }
1212
enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); }
13+
void nevermore__extern(void) { nevermore(); }

bindgen-tests/tests/expectations/tests/wrap-static-fns.rs

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/headers/wrap-static-fns.h

+4
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,7 @@ enum foo {
4040
static inline enum foo takes_enum(const enum foo f) {
4141
return f;
4242
}
43+
44+
static inline void nevermore() {
45+
while (1) { }
46+
}

bindgen/codegen/serialize.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,31 @@ impl<'a> CSerialize<'a> for Function {
102102

103103
// The name used for the wrapper self.
104104
let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix());
105+
105106
// The function's return type
106-
let ret_ty = signature.return_type();
107+
let ret_ty = {
108+
let type_id = signature.return_type();
109+
let item = ctx.resolve_item(type_id);
110+
let ret_ty = item.expect_type();
111+
112+
// Write `ret_ty`.
113+
ret_ty.serialize(ctx, item, stack, writer)?;
114+
115+
ret_ty
116+
};
107117

108-
// Write `ret_ty wrap_name(args) { return name(arg_names)' }`
109-
ret_ty.serialize(ctx, (), stack, writer)?;
118+
// Write `wrap_name(args`.
110119
write!(writer, " {}(", wrap_name)?;
111120
serialize_args(&args, ctx, writer)?;
112-
write!(writer, ") {{ return {}(", name)?;
121+
122+
// Write `) { name(` if the function returns void and `) { return name(` if it does not.
123+
if ret_ty.is_void() {
124+
write!(writer, ") {{ {}(", name)?;
125+
} else {
126+
write!(writer, ") {{ return {}(", name)?;
127+
}
128+
129+
// Write `arg_names); }`.
113130
serialize_sep(", ", args.iter(), ctx, writer, |(name, _), _, buf| {
114131
write!(buf, "{}", name).map_err(From::from)
115132
})?;

bindgen/ir/ty.rs

+4
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ impl Type {
124124
matches!(self.kind, TypeKind::Enum(..))
125125
}
126126

127+
/// Is this void?
128+
pub(crate) fn is_void(&self) -> bool {
129+
matches!(self.kind, TypeKind::Void)
130+
}
127131
/// Is this either a builtin or named type?
128132
pub(crate) fn is_builtin_or_type_param(&self) -> bool {
129133
matches!(

0 commit comments

Comments
 (0)