Repository navigation
The improper_ctypes lint is very weak #36464
Description
Activity
- addedA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.
on Sep 14, 2016 I think that the improper_ctypes lint should catch both of the extern declarations.
The enum should be caught, but the extern declarations should not, because code like following is entirely valid:
// in rust #[link_name="bar"] pub extern fn stuff(a: NotSoGood) { ... } // somewhere else, still in rust extern { fn bar(a: NotSoGood); }To explain, making functions be called using non-Rust calling convention does not invalidate passing rust data types back into Rust for functions implemented with non-Rust calling convention.
void foo(uint8_t a[16]);in C/C++ does not actually mean what it looks like. It actually meansvoid foo(uint8_t* a);. So the fault lies with C/C++ being confusing in this case.@nagisa: I agree that your code is valid, but you typed
externand notextern "C". There's a C ABI, and that ABI, as a practical matter, does not include passing arrays by value, since you can't pass arrays by value in C.Oddly, the actual x86_64 psABI does seem to think that arrays can be passed:
The classification of aggregate (structures and arrays) and union types works as follows: ...and I haven't found an example of Rust deviating from the psABI document, but I still suspect that almost (or maybe even exactly) 100% of cases where someone has actually attempted to pass an array into an
extern "C"function are incorrect.extern≡extern "C"Reacted by lolbinarycat- Wow, somehow I assumed the default was the Rust calling convention.
- addedC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.
on Jul 26, 2017 @nagisa (I know I'm a bit late, what can you do) In your example, rustc actually will warn on the
extern { fn }side of things. How is the trade-off different on theextern fnside?The
#[repr(C)] enumnow has a formal definition, so this issue looks like it can be closed.In your example, rustc actually will warn on the extern { fn } side of things.
Will it? All types in the example are
repr(C), so there is nothing to warn about on either of the function definition or declaration.Ah I guess there is still the case with sized arrays.
- addedA-FFIArea: Foreign function interface (FFI)Area: Foreign function interface (FFI)T-langRelevant to the language teamRelevant to the language team
on Nov 29, 2019 Ah I guess there is still the case with sized arrays.
Did #66305 fix this case? Can it be closed now?
The following code doesn't trigger
improper_ctypeslint. Should it not?#[repr(transparent)] pub struct Array([u64; 2]); #[no_mangle] pub unsafe extern "C" fn function(arg: Array) -> Array { arg }
Referred to in this issue
I guess the question above is: do arrays and structs follow the same calling convention? If no, then
improper_ctypeslint should be improved to warn in the previous exampleI believe this the ctypes lint isn't working correctly on that transparent array input, yes.
I have opened #116959 to cover the second case mentioned, because it is separate-ish. Closing.
- addedA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.and removedA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.
on Dec 21, 2024
This code compiles without warnings. I think that the improper_ctypes lint should catch both of the extern declarations.
The array case (
foo) is particularly nasty. On brief, insufficiently careful inspection, it looks like it matches:But it actually doesn't match that and instead seems to try to pass the array in packed form in
xmm0on x86_64. This is extra nasty because I think I've caughtrust-bindgengenerating bindings like this.