rust-lang / rust-lang/rust-bindgen

Making type template opaque has undesired behavior

Open
#869 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-templates I-failing-layout-test
Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

Input C/C++ Header
template<typename T>
struct Foo {
  void* a;
};

template<typename T>
class Bar {
  Foo<T> m;
};

class Baz {
  Bar<int> m;
};
Bindgen Invocation
$ bindgen input.hpp --opaque-type Foo
Actual Results
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Bar {
    pub m: u8,
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Baz {
    pub m: Bar,
}
#[test]
fn bindgen_test_layout_Baz() {
    assert_eq!(::std::mem::size_of::<Baz>() , 8usize , concat ! (
               "Size of: " , stringify ! ( Baz ) ));
    assert_eq! (::std::mem::align_of::<Baz>() , 8usize , concat ! (
                "Alignment of " , stringify ! ( Baz ) ));
    assert_eq! (unsafe {
                & ( * ( 0 as * const Baz ) ) . m as * const _ as usize } ,
                0usize , concat ! (
                "Alignment of field: " , stringify ! ( Baz ) , "::" ,
                stringify ! ( m ) ));
}
impl Clone for Baz {
    fn clone(&self) -> Self { *self }
}
#[test]
fn __bindgen_test_layout_Bar_open0_int_close0_instantiation() {
    assert_eq!(::std::mem::size_of::<Bar>() , 8usize , concat ! (
               "Size of template specialization: " , stringify ! ( Bar ) ));
    assert_eq!(::std::mem::align_of::<Bar>() , 8usize , concat ! (
               "Alignment of template specialization: " , stringify ! ( Bar )
               ));
}
Expected Results

As can be seen from the C++ code, Foo should have a pointer size, and Bar and Baz as well. However, Bar and Baz in this case only have 1 byte, while the layout test asserts they have 8 bytes.

Bar probably should have something like [u8; 8usize] or [usize; 2usize] instead.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the shown input.hpp header and bindgen input.hpp --opaque-type Foo, then inspect the generated layouts and assertions for Foo, Bar, and Baz. The fix is complete when opaque template containment gives Bar and Baz their expected pointer-sized layouts and the generated layout tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, rust
Domain
compilers, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.