KDAB / cxx-qt

Safe interop between Rust and Qt
https://kdab.github.io/cxx-qt/book/
1.06k stars 75 forks source link

Clang 17 return-type-c-linkage warning in qml-features #853

Open Be-ing opened 8 months ago

Be-ing commented 8 months ago
warning: qml-features@0.1.0: /home/be/sw/cxx-qt/build/cargo/build/x86_64-unknown-linux-gnu/debug/build/qml-features-732e3917cae6739e/out/cxx-qt-gen/src/rust_signals.cxx.cpp:531:51: warning: 'cxx_qt_rust_signals$cxxbridge1$route_arguments_rust_signals_1' has C-linkage specified, but returns user-defined type '::cxx_qt_rust_signals::CxxQtConstructorArguments1' which is incompatible with C [-Wreturn-type-c-linkage]
warning: qml-features@0.1.0:   531 | ::cxx_qt_rust_signals::CxxQtConstructorArguments1 cxx_qt_rust_signals$cxxbridge1$route_arguments_rust_signals_1(::QUrl const &arg0) noexcept;
warning: qml-features@0.1.0:       |                                                   ^
warning: qml-features@0.1.0: 1 warning generated.
warning: qml-features@0.1.0: /home/be/sw/cxx-qt/build/cargo/build/x86_64-unknown-linux-gnu/debug/build/qml-features-732e3917cae6739e/out/cxx-qt-gen/src/rust_properties.cxx.cpp:551:54: warning: 'cxx_qt_rust_properties$cxxbridge1$route_arguments_rust_properties_1' has C-linkage specified, but returns user-defined type '::cxx_qt_rust_properties::CxxQtConstructorArguments1' which is incompatible with C [-Wreturn-type-c-linkage]
warning: qml-features@0.1.0:   551 | ::cxx_qt_rust_properties::CxxQtConstructorArguments1 cxx_qt_rust_properties$cxxbridge1$route_arguments_rust_properties_1(bool arg0, ::QUrl const &arg1, ::QUrl const &arg2, ::QString const &arg3) noexcept;
warning: qml-features@0.1.0:       |                                                      ^
warning: qml-features@0.1.0: 1 warning generated.
ahayzen-kdab commented 8 months ago

@LeonMatthesKDAB any ideas what might be wrong here, looks like your constructor code is declaring a CXX method returning a shared struct ?

LeonMatthesKDAB commented 8 months ago

That's just a shared CXX type, so might be a CXX issue. :thinking: Can you try reproducing with just a CXX Bridge and a shared type?

ahayzen-kdab commented 3 weeks ago

So investigating this I've found it is linked to using references in the shared struct.

If they are a pointer or a value the warning does not occur.

@LeonMatthesKDAB wondered if we could automatically convert between reference and pointer when required.

Code with a reference

#[cxx::bridge]
mod ffi {
    struct SharedStruct<'a> {
        value: &'a u32,
    }

    extern "Rust" {
        fn test2() -> SharedStruct<'static>;
    }
}

fn test2() -> ffi::SharedStruct<'static> {
    ffi::SharedStruct { value: &2 }
}

fn main() {
    println!("Hello, world!");

    let shared2 = test2();
    println!("Shared: {}", shared2.value);
}

If you run this with a recent clang version the following occurs

$ CC=clang CXX=clang++ cargo run
warning: sharedtype@0.1.0: /var/home/andrew/Projects/cxx/sharedtype/target/debug/build/sharedtype-d22b5f580a4bbff5/out/cxxbridge/sources/sharedtype/src/main.rs.cc:16:16: warning: 'cxxbridge1$test2' has C-linkage specified, but returns user-defined type '::SharedStruct' which is incompatible with C [-Wreturn-type-c-linkage]
warning: sharedtype@0.1.0:    16 | ::SharedStruct cxxbridge1$test2() noexcept;
warning: sharedtype@0.1.0:       |                ^
warning: sharedtype@0.1.0: 1 warning generated.
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/sharedtype`
Hello, world!
Shared: 2

Code with a pointer

#[cxx::bridge]
mod ffi {
    struct SharedStruct {
        value: *mut u32,
    }

    extern "Rust" {
        fn test2() -> SharedStruct;
    }
}

fn test2() -> ffi::SharedStruct {
    ffi::SharedStruct {
        value: Box::into_raw(Box::new(2)),
    }
}

fn main() {
    println!("Hello, world!");

    let shared2 = test2();
    println!("Shared: {:?}", unsafe { shared2.value.as_mut() });
}

If you use a pointer it is fine though (and it also works for just u32).

$ CC=clang CXX=clang++ cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/sharedtype`
Hello, world!
Shared: Some(2)