summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-04-03 14:36:59 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-04-04 01:05:34 +0200
commit8f1e5f5ad4fff230b06cdfca868266a28ada3881 (patch)
tree7fbf20f8154e3807dbf29a8726d6e050e15e59b0
parentf31340159e8a30882a7a41dd7838b87a7d6fe753 (diff)
ir: Force the D1 destructor symbol even in older libclang versions.
-rw-r--r--src/ir/function.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/ir/function.rs b/src/ir/function.rs
index fd88b657..2c588fdd 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -114,6 +114,7 @@ fn get_abi(cc: CXCallingConv) -> Option<abi::Abi> {
pub fn cursor_mangling(ctx: &BindgenContext,
cursor: &clang::Cursor)
-> Option<String> {
+ use clang_sys;
if !ctx.options().enable_mangling {
return None;
}
@@ -131,10 +132,37 @@ pub fn cursor_mangling(ctx: &BindgenContext,
}
// Try to undo backend linkage munging (prepended _, generally)
+ //
+ // TODO(emilio): This is wrong when the target system is not the host
+ // system. See https://github.com/servo/rust-bindgen/issues/593
if cfg!(target_os = "macos") {
mangling.remove(0);
}
+ if cursor.kind() == clang_sys::CXCursor_Destructor {
+ // With old (3.8-) libclang versions, and the Itanium ABI, clang returns
+ // the "destructor group 0" symbol, which means that it'll try to free
+ // memory, which definitely isn't what we want.
+ //
+ // Explicitly force the destructor group 1 symbol.
+ //
+ // See http://refspecs.linuxbase.org/cxxabi-1.83.html#mangling-special
+ // for the reference, and http://stackoverflow.com/a/6614369/1091587 for
+ // a more friendly explanation.
+ //
+ // We don't need to do this for constructors since clang seems to always
+ // have returned the C1 constructor.
+ //
+ // FIXME(emilio): Can a legit symbol in other ABIs end with this string?
+ // I don't think so, but if it can this would become a linker error
+ // anyway, not an invalid free at runtime.
+ if mangling.ends_with("D0Ev") {
+ let new_len = mangling.len() - 4;
+ mangling.truncate(new_len);
+ mangling.push_str("D1Ev");
+ }
+ }
+
Some(mangling)
}