Skip to content

Commit a813721

Browse files
authored
Merge pull request #980 from dtolnay/unwind
Wrap all trait impls exposed to C++ in prevent_unwind
2 parents c9ee101 + dd78e66 commit a813721

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

macro/src/expand.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -194,78 +194,92 @@ fn expand_struct_operators(strct: &Struct) -> TokenStream {
194194
Trait::PartialEq => {
195195
let link_name = mangle::operator(&strct.name, "eq");
196196
let local_name = format_ident!("__operator_eq_{}", strct.name.rust);
197+
let prevent_unwind_label = format!("::{} as PartialEq>::eq", strct.name.rust);
197198
operators.extend(quote_spanned! {span=>
198199
#[doc(hidden)]
199200
#[export_name = #link_name]
200201
extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
201-
*lhs == *rhs
202+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
203+
::cxx::private::prevent_unwind(__fn, || *lhs == *rhs)
202204
}
203205
});
204206

205207
if !derive::contains(&strct.derives, Trait::Eq) {
206208
let link_name = mangle::operator(&strct.name, "ne");
207209
let local_name = format_ident!("__operator_ne_{}", strct.name.rust);
210+
let prevent_unwind_label = format!("::{} as PartialEq>::ne", strct.name.rust);
208211
operators.extend(quote_spanned! {span=>
209212
#[doc(hidden)]
210213
#[export_name = #link_name]
211214
extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
212-
*lhs != *rhs
215+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
216+
::cxx::private::prevent_unwind(__fn, || *lhs != *rhs)
213217
}
214218
});
215219
}
216220
}
217221
Trait::PartialOrd => {
218222
let link_name = mangle::operator(&strct.name, "lt");
219223
let local_name = format_ident!("__operator_lt_{}", strct.name.rust);
224+
let prevent_unwind_label = format!("::{} as PartialOrd>::lt", strct.name.rust);
220225
operators.extend(quote_spanned! {span=>
221226
#[doc(hidden)]
222227
#[export_name = #link_name]
223228
extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
224-
*lhs < *rhs
229+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
230+
::cxx::private::prevent_unwind(__fn, || *lhs < *rhs)
225231
}
226232
});
227233

228234
let link_name = mangle::operator(&strct.name, "le");
229235
let local_name = format_ident!("__operator_le_{}", strct.name.rust);
236+
let prevent_unwind_label = format!("::{} as PartialOrd>::le", strct.name.rust);
230237
operators.extend(quote_spanned! {span=>
231238
#[doc(hidden)]
232239
#[export_name = #link_name]
233240
extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
234-
*lhs <= *rhs
241+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
242+
::cxx::private::prevent_unwind(__fn, || *lhs <= *rhs)
235243
}
236244
});
237245

238246
if !derive::contains(&strct.derives, Trait::Ord) {
239247
let link_name = mangle::operator(&strct.name, "gt");
240248
let local_name = format_ident!("__operator_gt_{}", strct.name.rust);
249+
let prevent_unwind_label = format!("::{} as PartialOrd>::gt", strct.name.rust);
241250
operators.extend(quote_spanned! {span=>
242251
#[doc(hidden)]
243252
#[export_name = #link_name]
244253
extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
245-
*lhs > *rhs
254+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
255+
::cxx::private::prevent_unwind(__fn, || *lhs > *rhs)
246256
}
247257
});
248258

249259
let link_name = mangle::operator(&strct.name, "ge");
250260
let local_name = format_ident!("__operator_ge_{}", strct.name.rust);
261+
let prevent_unwind_label = format!("::{} as PartialOrd>::ge", strct.name.rust);
251262
operators.extend(quote_spanned! {span=>
252263
#[doc(hidden)]
253264
#[export_name = #link_name]
254265
extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
255-
*lhs >= *rhs
266+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
267+
::cxx::private::prevent_unwind(__fn, || *lhs >= *rhs)
256268
}
257269
});
258270
}
259271
}
260272
Trait::Hash => {
261273
let link_name = mangle::operator(&strct.name, "hash");
262274
let local_name = format_ident!("__operator_hash_{}", strct.name.rust);
275+
let prevent_unwind_label = format!("::{} as Hash>::hash", strct.name.rust);
263276
operators.extend(quote_spanned! {span=>
264277
#[doc(hidden)]
265278
#[export_name = #link_name]
266279
#[allow(clippy::cast_possible_truncation)]
267280
extern "C" fn #local_name(this: &#ident) -> usize {
268-
::cxx::private::hash(this)
281+
let __fn = concat!("<", module_path!(), #prevent_unwind_label);
282+
::cxx::private::prevent_unwind(__fn, || ::cxx::private::hash(this))
269283
}
270284
});
271285
}
@@ -1222,13 +1236,16 @@ fn expand_rust_box(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
12221236
let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span);
12231237
let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span);
12241238
let unsafe_token = format_ident!("unsafe", span = begin_span);
1239+
let prevent_unwind_drop_label = format!("::{} as Drop>::drop", ident);
12251240

12261241
quote_spanned! {end_span=>
12271242
#[doc(hidden)]
12281243
#unsafe_token impl #impl_generics ::cxx::private::ImplBox for #ident #ty_generics {}
12291244
#[doc(hidden)]
12301245
#[export_name = #link_alloc]
12311246
unsafe extern "C" fn #local_alloc #impl_generics() -> *mut ::cxx::core::mem::MaybeUninit<#ident #ty_generics> {
1247+
// No prevent_unwind: the global allocator is not allowed to panic.
1248+
//
12321249
// TODO: replace with Box::new_uninit when stable.
12331250
// https://doc.rust-lang.org/std/boxed/struct.Box.html#method.new_uninit
12341251
// https://github.com/rust-lang/rust/issues/63291
@@ -1237,12 +1254,14 @@ fn expand_rust_box(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
12371254
#[doc(hidden)]
12381255
#[export_name = #link_dealloc]
12391256
unsafe extern "C" fn #local_dealloc #impl_generics(ptr: *mut ::cxx::core::mem::MaybeUninit<#ident #ty_generics>) {
1257+
// No prevent_unwind: the global allocator is not allowed to panic.
12401258
::cxx::alloc::boxed::Box::from_raw(ptr);
12411259
}
12421260
#[doc(hidden)]
12431261
#[export_name = #link_drop]
12441262
unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::cxx::alloc::boxed::Box<#ident #ty_generics>) {
1245-
::cxx::core::ptr::drop_in_place(this);
1263+
let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label);
1264+
::cxx::private::prevent_unwind(__fn, || ::cxx::core::ptr::drop_in_place(this));
12461265
}
12471266
}
12481267
}
@@ -1275,49 +1294,58 @@ fn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
12751294
let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span);
12761295
let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span);
12771296
let unsafe_token = format_ident!("unsafe", span = begin_span);
1297+
let prevent_unwind_drop_label = format!("::{} as Drop>::drop", elem);
12781298

12791299
quote_spanned! {end_span=>
12801300
#[doc(hidden)]
12811301
#unsafe_token impl #impl_generics ::cxx::private::ImplVec for #elem #ty_generics {}
12821302
#[doc(hidden)]
12831303
#[export_name = #link_new]
12841304
unsafe extern "C" fn #local_new #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) {
1305+
// No prevent_unwind: cannot panic.
12851306
::cxx::core::ptr::write(this, ::cxx::private::RustVec::new());
12861307
}
12871308
#[doc(hidden)]
12881309
#[export_name = #link_drop]
12891310
unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) {
1290-
::cxx::core::ptr::drop_in_place(this);
1311+
let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label);
1312+
::cxx::private::prevent_unwind(__fn, || ::cxx::core::ptr::drop_in_place(this));
12911313
}
12921314
#[doc(hidden)]
12931315
#[export_name = #link_len]
12941316
unsafe extern "C" fn #local_len #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> usize {
1317+
// No prevent_unwind: cannot panic.
12951318
(*this).len()
12961319
}
12971320
#[doc(hidden)]
12981321
#[export_name = #link_capacity]
12991322
unsafe extern "C" fn #local_capacity #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> usize {
1323+
// No prevent_unwind: cannot panic.
13001324
(*this).capacity()
13011325
}
13021326
#[doc(hidden)]
13031327
#[export_name = #link_data]
13041328
unsafe extern "C" fn #local_data #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> *const #elem #ty_generics {
1329+
// No prevent_unwind: cannot panic.
13051330
(*this).as_ptr()
13061331
}
13071332
#[doc(hidden)]
13081333
#[export_name = #link_reserve_total]
13091334
unsafe extern "C" fn #local_reserve_total #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, new_cap: usize) {
1335+
// No prevent_unwind: the global allocator is not allowed to panic.
13101336
(*this).reserve_total(new_cap);
13111337
}
13121338
#[doc(hidden)]
13131339
#[export_name = #link_set_len]
13141340
unsafe extern "C" fn #local_set_len #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, len: usize) {
1341+
// No prevent_unwind: cannot panic.
13151342
(*this).set_len(len);
13161343
}
13171344
#[doc(hidden)]
13181345
#[export_name = #link_clear]
13191346
unsafe extern "C" fn #local_clear #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) {
1320-
(*this).clear();
1347+
let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label);
1348+
::cxx::private::prevent_unwind(__fn, || (*this).clear());
13211349
}
13221350
}
13231351
}

0 commit comments

Comments
 (0)