Skip to content

Commit d4175c7

Browse files
committed
Bug 1831467 - Avoid more UB from transmuting a ref to a ref with interior mutability. r=emilio, a=dsmith
aka one specific change in LLVM 16 introducing UB in Rust, take 3? 4? This time, we have multiple types like: #[xpcom(implement(nsISomething))] struct Foo { foo: RefCell<Something>, } impl Foo { fn from_interface(obj: &nsISomething) -> &Self { unsafe { ::std::mem::transmute(obj) } } } At first glance, this looks innocuous. But the problem is that nsISomething, as far as LLVM is informed by Rust, is readonly, but Foo, via the RefCell, has interious mutability. LLVM ends up assuming that any mutability that happens to that returned &Foo can't happen, and removes it. This is yet another case where rust-lang/rust#111229 would save our feet from this footgun LLVM 16 added and that the rust compiler doesn't help us prevent the least. Differential Revision: https://phabricator.services.mozilla.com/D183569 *** Bug 1831467 fix comment a=dsmith
1 parent 3a39e75 commit d4175c7

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

xpcom/idl-parser/xpidl/rust.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,21 @@ def print_rust_bindings(idl, fd, relpath):
445445
///
446446
/// XPCOM interfaces in general are not safe to send across threads.
447447
__nosync: ::std::marker::PhantomData<::std::rc::Rc<u8>>,
448+
449+
// Make the rust compiler aware that there might be interior mutability
450+
// in what actually implements the interface. This works around UB
451+
// introduced by
452+
// https://github.com/llvm/llvm-project/commit/01859da84bad95fd51d6a03b08b60c660e642a4f
453+
// that a rust lint would make blatantly obvious, but doesn't exist.
454+
// (See https://github.com/rust-lang/rust/issues/111229).
455+
// This prevents optimizations, but those optimizations weren't available
456+
// before rustc switched to LLVM 16, and they now cause problems because
457+
// of the UB.
458+
// Until there's a lint available to find all our UB, it's simpler to
459+
// avoid the UB in the first place, at the cost of preventing optimizations
460+
// in places that don't cause UB. But again, those optimizations weren't
461+
// available before.
462+
__maybe_interior_mutability: ::std::cell::UnsafeCell<[u8; 0]>,
448463
}
449464
450465
// Implementing XpCom for an interface exposes its IID, which allows for easy

0 commit comments

Comments
 (0)