Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improper_ctypes complains about types that contain PhantomData #34798

Closed
Ms2ger opened this Issue Jul 13, 2016 · 5 comments

Comments

Projects
None yet
6 participants
@Ms2ger
Copy link
Contributor

Ms2ger commented Jul 13, 2016

#[repr(C)]
pub struct Foo(::std::marker::PhantomData<i32>);
extern {
    pub fn f(foo: *mut Foo);
}
fn main() {}
warning: found non-foreign-function-safe member in struct marked #[repr(C)]: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type, #[warn(improper_ctypes)] on by default
 --> <anon>:5:19
5 |>     pub fn f(foo: *mut Foo);
  |>                   ^^^^^^^^

This comes up in bindings generated from C code that contains unions (the __BindgenUnionField type).

@TimNN

This comment has been minimized.

Copy link
Contributor

TimNN commented Jul 13, 2016

The problem, as far as I know, is that *mut Foo really is not ffi safe.

This is because Zero Sized Types (which Foo is) as well as pointers to Zero Sized Types are not ffi safe (again, as far as I know).

@oli-obk

This comment has been minimized.

Copy link
Contributor

oli-obk commented Jul 13, 2016

it also happens (although with a slightly different message) when the type is not ZST: https://is.gd/8529c8

warning: found non-foreign-function-safe member in struct marked #[repr(C)]: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type, #[warn(improper_ctypes)] on by default
 --> <anon>:9:19
9 |>     pub fn f(foo: *mut Foo);
  |> 
@emilio

This comment has been minimized.

Copy link
Contributor

emilio commented Sep 8, 2016

Unfortunately, we need to use phantom data to use bindgen with C++, because a struct like:

template<typename T>
struct Foo {
    int bar;
};

The only way we can represent that in rust is

struct Foo<T> {
   bar: c_int,
   _phantom: PhantomData<T>,
}
@d3zd3z

This comment has been minimized.

Copy link

d3zd3z commented Dec 4, 2016

I've run into this issue with something similar

use std::marker::PhantomData;

fn main() {
    let buffer = vec![0u8; 16];
    let data = Data {
        ptr: &buffer[0],
        phantom: PhantomData,
    };
    unsafe { bogus(&data) };
}

#[repr(C)]
struct Data<'a> {
    ptr: *const u8,
    phantom: PhantomData<&'a [u8]>,
}

extern "C" {
    fn bogus(data: *const Data);
}

which generates the same kind of warning:

warning: found non-foreign-function-safe member in struct marked #[repr(C)]: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type, #[warn(improper_ctypes)] on by default
  --> src/main.rs:19:20
   |
19 |     fn bogus(data: *const Data);
   |                    ^^^^^^^^^^^

My real use-case has other fields in the struct, which are needed to match the C API.

@rillian

This comment has been minimized.

Copy link
Contributor

rillian commented Jan 25, 2017

I did a little poking around to understand how unsafe this is. In https://play.rust-lang.org/?gist=24634425b2bd8707c73f09e418900ec5 you can see that the PhantomData really is zero-size; it has the same address as the subsequent struct field.

However, it is reported in debuginfo. So while passing its address across the ffi boundary is I think covered by the existing safety rules, a debugger could be confused by the duplicate labels on the struct.

emilio added a commit to emilio/rust that referenced this issue Feb 2, 2017

emilio added a commit to emilio/rust that referenced this issue Feb 3, 2017

emilio added a commit to emilio/rust that referenced this issue Feb 3, 2017

emilio added a commit to emilio/rust that referenced this issue Feb 3, 2017

emilio added a commit to emilio/rust that referenced this issue Feb 3, 2017

frewsxcv added a commit to frewsxcv/rust that referenced this issue Feb 7, 2017

Rollup merge of rust-lang#39462 - emilio:improper-ctypes, r=nikomatsakis
lint/ctypes: Don't warn on sized structs with PhantomData.

Fixes rust-lang#34798

frewsxcv added a commit to frewsxcv/rust that referenced this issue Feb 8, 2017

Rollup merge of rust-lang#39462 - emilio:improper-ctypes, r=nikomatsakis
lint/ctypes: Don't warn on sized structs with PhantomData.

Fixes rust-lang#34798

frewsxcv added a commit to frewsxcv/rust that referenced this issue Feb 8, 2017

Rollup merge of rust-lang#39462 - emilio:improper-ctypes, r=nikomatsakis
lint/ctypes: Don't warn on sized structs with PhantomData.

Fixes rust-lang#34798

frewsxcv added a commit to frewsxcv/rust that referenced this issue Feb 8, 2017

Rollup merge of rust-lang#39462 - emilio:improper-ctypes, r=nikomatsakis
lint/ctypes: Don't warn on sized structs with PhantomData.

Fixes rust-lang#34798

@bors bors closed this in #39462 Feb 8, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.