Skip to content

Commit ac0fa3b

Browse files
Caellianemilio
authored andcommitted
Use NonNull for C++ references
- Make feature disabled by default until usability concerns are resolved. - Add test for --nonnull-references argument Signed-off-by: Tin Švagelj <[email protected]>
1 parent e2460d9 commit ac0fa3b

File tree

5 files changed

+109
-0
lines changed

5 files changed

+109
-0
lines changed

bindgen-tests/tests/expectations/tests/references.rs

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// bindgen-flags: --nonnull-references
2+
3+
struct Container {
4+
int *normalPointer;
5+
const int *constPointer;
6+
int &normalRef;
7+
const int &constRef;
8+
int *&pointerRef;
9+
const int *&constPointerRef;
10+
};
11+
12+
int &refReturningFunction();
13+
14+
void functionConsumingRef(int &someRef, float normalArgument,
15+
const int &constRef);
16+
17+
void functionConsumingPointerRef(int* &pointerRef);

bindgen/codegen/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4371,6 +4371,12 @@ impl TryToRustTy for Type {
43714371
if inner_ty.canonical_type(ctx).is_function() || is_objc_pointer
43724372
{
43734373
Ok(ty)
4374+
} else if ctx.options().generate_cxx_nonnull_references &&
4375+
matches!(self.kind(), TypeKind::Reference(_))
4376+
{
4377+
// It's UB to pass null values in place of C++ references
4378+
let prefix = ctx.trait_prefix();
4379+
Ok(syn::parse_quote! { ::#prefix::ptr::NonNull<#ty> })
43744380
} else {
43754381
Ok(ty.to_ptr(is_const))
43764382
}

bindgen/options/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ struct BindgenCommand {
258258
/// Use extern crate instead of use for objc.
259259
#[arg(long)]
260260
objc_extern_crate: bool,
261+
/// Use `NonNull` in place of raw pointers for C++ references.
262+
#[arg(long)]
263+
nonnull_references: bool,
261264
/// Generate block signatures instead of void pointers.
262265
#[arg(long)]
263266
generate_block: bool,
@@ -590,6 +593,7 @@ where
590593
no_doc_comments,
591594
no_recursive_allowlist,
592595
objc_extern_crate,
596+
nonnull_references,
593597
generate_block,
594598
generate_cstr,
595599
block_extern_crate,
@@ -921,6 +925,7 @@ where
921925
no_doc_comments => |b, _| b.generate_comments(false),
922926
no_recursive_allowlist => |b, _| b.allowlist_recursively(false),
923927
objc_extern_crate,
928+
nonnull_references => |b, _| b.generate_cxx_nonnull_references(true),
924929
generate_block,
925930
generate_cstr,
926931
block_extern_crate,

bindgen/options/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,26 @@ options! {
14791479
},
14801480
as_args: |value, args| (!value).as_args(args, "--no-doc-comments"),
14811481
},
1482+
/// Whether to generate [`NonNull`] pointers for C++ references.
1483+
///
1484+
/// [`NonNull`]: core::ptr::NonNull
1485+
generate_cxx_nonnull_references: bool {
1486+
default: false,
1487+
methods: {
1488+
/// Generate `NonNull` pointers in place of raw pointers for C++
1489+
/// references.
1490+
///
1491+
/// This option is disabled by default:
1492+
///
1493+
/// Enabling it erases information about constness in generated
1494+
/// code, and `NonNull` is more cumbersome to use than raw pointers.
1495+
pub fn generate_cxx_nonnull_references(mut self, doit: bool) -> Self {
1496+
self.options.generate_cxx_nonnull_references = doit;
1497+
self
1498+
}
1499+
},
1500+
as_args: |value, args| value.as_args(args, "--nonnull-references"),
1501+
},
14821502
/// Whether to generate inline functions.
14831503
generate_inline_functions: bool {
14841504
methods: {

0 commit comments

Comments
 (0)