Description
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();
};