Skip to content

Commit 6adb002

Browse files
author
bors-servo
authored
Auto merge of #1240 - emilio:virtual-dtor-fix, r=fitzgen
ir: Choose the right mangling for destructors on all codepaths. Fixes #1133.
2 parents 821b133 + 29705c2 commit 6adb002

File tree

6 files changed

+55
-5
lines changed

6 files changed

+55
-5
lines changed

bindgen-integration/cpp/Test.cc

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
const int Test::COUNTDOWN[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
44
const int* Test::COUNTDOWN_PTR = Test::COUNTDOWN;
55

6+
unsigned VirtualDestructor::sDestructorCount = 0;
7+
VirtualDestructor::~VirtualDestructor() {
8+
sDestructorCount++;
9+
}
10+
11+
unsigned InheritsFromVirtualDestructor::sDestructorCount = 0;
12+
InheritsFromVirtualDestructor::InheritsFromVirtualDestructor() = default;
13+
14+
InheritsFromVirtualDestructor::~InheritsFromVirtualDestructor() {
15+
sDestructorCount++;
16+
}
17+
618
const int* Test::countdown() {
719
return COUNTDOWN;
820
}

bindgen-integration/cpp/Test.h

+13
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ class ITest {
1919
virtual void foo() = 0;
2020
};
2121

22+
class VirtualDestructor {
23+
public:
24+
static unsigned sDestructorCount;
25+
virtual ~VirtualDestructor() = 0;
26+
};
27+
28+
class InheritsFromVirtualDestructor final : public VirtualDestructor {
29+
public:
30+
static unsigned sDestructorCount;
31+
InheritsFromVirtualDestructor();
32+
~InheritsFromVirtualDestructor() final;
33+
};
34+
2235
namespace testing {
2336

2437
typedef Test TypeAlias;

bindgen-integration/src/lib.rs

+19
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,22 @@ fn test_destructors() {
260260

261261
assert!(v, "Should've been restored when going out of scope");
262262
}
263+
264+
impl Drop for bindings::InheritsFromVirtualDestructor {
265+
fn drop(&mut self) {
266+
unsafe { bindings::InheritsFromVirtualDestructor_InheritsFromVirtualDestructor_destructor(self) }
267+
}
268+
}
269+
270+
#[test]
271+
fn test_virtual_dtor() {
272+
unsafe {
273+
{
274+
let b = bindings::InheritsFromVirtualDestructor::new();
275+
// Let it go out of scope.
276+
}
277+
278+
assert_eq!(bindings::InheritsFromVirtualDestructor_sDestructorCount, 1);
279+
assert_eq!(bindings::VirtualDestructor_sDestructorCount, 1);
280+
}
281+
}

src/codegen/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,7 @@ impl MethodCodegen for Method {
19911991
}
19921992
});
19931993

1994+
// TODO(emilio): We could generate final stuff at least.
19941995
if self.is_virtual() {
19951996
return; // FIXME
19961997
}

src/ir/function.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ pub fn cursor_mangling(
245245
cursor: &clang::Cursor,
246246
) -> Option<String> {
247247
use clang_sys;
248+
248249
if !ctx.options().enable_mangling {
249250
return None;
250251
}
@@ -256,8 +257,14 @@ pub fn cursor_mangling(
256257
return None;
257258
}
258259

260+
let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor;
259261
if let Ok(mut manglings) = cursor.cxx_manglings() {
260-
if let Some(m) = manglings.pop() {
262+
while let Some(m) = manglings.pop() {
263+
// Only generate the destructor group 1, see below.
264+
if is_destructor && !m.ends_with("D1Ev") {
265+
continue;
266+
}
267+
261268
return Some(m);
262269
}
263270
}
@@ -267,7 +274,7 @@ pub fn cursor_mangling(
267274
return None;
268275
}
269276

270-
if cursor.kind() == clang_sys::CXCursor_Destructor {
277+
if is_destructor {
271278
// With old (3.8-) libclang versions, and the Itanium ABI, clang returns
272279
// the "destructor group 0" symbol, which means that it'll try to free
273280
// memory, which definitely isn't what we want.

tests/expectations/tests/virtual_dtor.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/* automatically generated by rust-bindgen */
22

3-
43
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
54

6-
75
#[repr(C)]
86
pub struct nsSlots__bindgen_vtable(::std::os::raw::c_void);
97
#[repr(C)]
@@ -30,6 +28,6 @@ impl Default for nsSlots {
3028
}
3129
}
3230
extern "C" {
33-
#[link_name = "\u{1}_ZN7nsSlotsD0Ev"]
31+
#[link_name = "\u{1}_ZN7nsSlotsD1Ev"]
3432
pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots);
3533
}

0 commit comments

Comments
 (0)