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

noexcept not passed to derived wrapper class #1435

Open
SteffenLindner opened this issue Feb 10, 2025 · 2 comments
Open

noexcept not passed to derived wrapper class #1435

SteffenLindner opened this issue Feb 10, 2025 · 2 comments

Comments

@SteffenLindner
Copy link

SteffenLindner commented Feb 10, 2025

Describe the bug
When defining a virtual noexcept method in a C++ class that is derived using #[subclass(superclass("MyCppClass"))], the generated wrapper methods do not include the noexcept statement, leading to a compiler error due to looser exception statement.

To Reproduce

// src/code.hpp
#pragma once
class SuperClass
{
public:
    virtual void doSomething() const noexcept = 0;
    virtual ~SuperClass() {};
};
// build.rs
fn main() -> miette::Result<()> {
    let mut b = autocxx_build::Builder::new("src/main.rs", &["./src"])
        .extra_clang_args(&["-std=c++17"])
        .auto_allowlist(true)
        .build()?;

    b.flag_if_supported("-std=c++17").compile("noexcept-test");
    println!("cargo:rerun-if-changed=src/main.rs");
    println!("cargo:rerun-if-changed=src/code.hpp");
    Ok(())
}
// src/main.rs
use autocxx::prelude::*;
use autocxx::subclass::prelude::*;
use ffi::SuperClass_methods;

include_cpp! {
    #include "code.hpp"
    safety!(unsafe) // unsafety policy; see docs
}

#[subclass(superclass("SuperClass"))]
#[derive(Default)]
pub struct DerivedStruct {}

impl ffi::SuperClass_methods for DerivedStruct {
    fn doSomething(&self) {
        println!("Do something");
    }
}

fn main() {
    let t = DerivedStruct::default_rust_owned();
    t.borrow().doSomething();
}

Expected behavior
Print statement is executed of doSomething call, which is done if the noexcept is removed from the virtual method.

Additional context
Error:

cargo:warning=In file included from /home/XXX/autocxx-bugs/noexcept/target/debug/build/noexcept-568b2dad4acfbf95/out/autocxx-build-dir/cxx/gen0.cxx:2: cargo:warning=/home/XXX/autocxx-bugs/noexcept/target/debug/build/noexcept-568b2dad4acfbf95/out/autocxx-build-dir/include/autocxxgen_ffi.h:41:6: error: looser exception specification on overriding virtual function 'virtual void DerivedStructCpp::doSomething() const' cargo:warning= 41 | void doSomething() const; cargo:warning= | ^~~~~~~~~~~ cargo:warning=In file included from /home/XXX/autocxx-bugs/noexcept/target/debug/build/noexcept-568b2dad4acfbf95/out/autocxx-build-dir/cxx/gen0.cxx:1: cargo:warning=./src/code.hpp:5:18: note: overridden function is 'virtual void SuperClass::doSomething() const noexcept' cargo:warning= 5 | virtual void doSomething() const noexcept = 0;

I belive it should be rather straightforward to also pass the noexcept to the generated code by autocxx / cxx.

In the generated C++ code, the noexcept is missing:

// XX//autocxxgen_ffi.h
struct DerivedStructHolder;
class DerivedStructCpp : public SuperClass
{
public:
inline  DerivedStructCpp(rust::Box<DerivedStructHolder> arg0) : obs(std::move(arg0)) {  }
void doSomething() const;
const SuperClass& As_SuperClass() const { return *this; }
SuperClass& As_SuperClass_mut() { return *this; }
void DerivedStructCpp_remove_ownership() const;
private:rust::Box<DerivedStructHolder> obs;
void really_remove_ownership();

};
@adetaylor
Copy link
Collaborator

Thanks for the report - please could you submit a PR with a test case to integration_tests.rs.

SteffenLindner added a commit to SteffenLindner/autocxx-noexcept that referenced this issue Feb 10, 2025
@SteffenLindner
Copy link
Author

Sure, I added a failing test case in #1436.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants