From bb85d448996442e19bc6ac5ecf4efbbad31fd0aa Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Tue, 1 Oct 2024 22:21:52 +0000 Subject: [PATCH] Bug 1440207 - Part 5: Disable UniqueFileHandle for RUST_BINDGEN, r=emilio,glandium Apparently rust bindgen uses a hack which assumes all specializations of `UniquePtr` have the basic layout and use a pointer member with an empty deleter. This incorrect assumption unfortunately comes up for UniqueFileHandle, which replaces the pointer type using the deleter with a file handle helper type. As this fails to build with RUST_BINDGEN, this patch takes the same approach as bug 1802320, and just disables building these types when building headers for bindgen. This does not fix the general issue of bindgen making incorrect assumptions about the layout of UniquePtr with non-default deleters. Ideally, all non-default deleters should be made opaque. Differential Revision: https://phabricator.services.mozilla.com/D223628 --- mfbt/UniquePtrExtensions.h | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/mfbt/UniquePtrExtensions.h b/mfbt/UniquePtrExtensions.h index c93f76a00871..565d4bf1fcee 100644 --- a/mfbt/UniquePtrExtensions.h +++ b/mfbt/UniquePtrExtensions.h @@ -93,28 +93,29 @@ struct FreePolicy { void operator()(const void* ptr) { free(const_cast(ptr)); } }; -#if defined(XP_WIN) +#if !defined(RUST_BINDGEN) +# if defined(XP_WIN) // Can't include to get the actual definition of HANDLE // because of namespace pollution. typedef void* FileHandleType; -#elif defined(XP_UNIX) +# elif defined(XP_UNIX) typedef int FileHandleType; -#else -# error "Unsupported OS?" -#endif +# else +# error "Unsupported OS?" +# endif struct FileHandleHelper { MOZ_IMPLICIT FileHandleHelper(FileHandleType aHandle) : mHandle(aHandle) { -#if defined(XP_UNIX) && (defined(DEBUG) || defined(FUZZING)) +# if defined(XP_UNIX) && (defined(DEBUG) || defined(FUZZING)) MOZ_RELEASE_ASSERT(aHandle == kInvalidHandle || aHandle > 2); -#endif +# endif } MOZ_IMPLICIT constexpr FileHandleHelper(std::nullptr_t) : mHandle(kInvalidHandle) {} bool operator!=(std::nullptr_t) const { -#ifdef XP_WIN +# ifdef XP_WIN // Windows uses both nullptr and INVALID_HANDLE_VALUE (-1 cast to // HANDLE) in different situations, but nullptr is more reliably // null while -1 is also valid input to some calls that take @@ -123,20 +124,20 @@ struct FileHandleHelper { if (mHandle == (void*)-1) { return false; } -#endif +# endif return mHandle != kInvalidHandle; } operator FileHandleType() const { return mHandle; } -#ifdef XP_WIN +# ifdef XP_WIN // NSPR uses an integer type for PROsfd, so this conversion is // provided for working with it without needing reinterpret casts // everywhere. operator std::intptr_t() const { return reinterpret_cast(mHandle); } -#endif +# endif // When there's only one user-defined conversion operator, the // compiler will use that to derive equality, but that doesn't work @@ -148,13 +149,13 @@ struct FileHandleHelper { private: FileHandleType mHandle; -#ifdef XP_WIN +# ifdef XP_WIN // See above for why this is nullptr. (Also, INVALID_HANDLE_VALUE // can't be expressed as a constexpr.) static constexpr FileHandleType kInvalidHandle = nullptr; -#else +# else static constexpr FileHandleType kInvalidHandle = -1; -#endif +# endif }; struct FileHandleDeleter { @@ -162,6 +163,7 @@ struct FileHandleDeleter { using receiver = FileHandleType; MFBT_API void operator()(FileHandleHelper aHelper); }; +#endif #if defined(XP_DARWIN) && !defined(RUST_BINDGEN) struct MachPortHelper { @@ -215,17 +217,19 @@ struct MachPortSetDeleter { template using UniqueFreePtr = UniquePtr>; +#if !defined(RUST_BINDGEN) // A RAII class for the OS construct used for open files and similar // objects: a file descriptor on Unix or a handle on Windows. using UniqueFileHandle = UniquePtr; -#ifndef __wasm__ +# ifndef __wasm__ // WASI does not have `dup` MFBT_API UniqueFileHandle DuplicateFileHandle(detail::FileHandleType aFile); inline UniqueFileHandle DuplicateFileHandle(const UniqueFileHandle& aFile) { return DuplicateFileHandle(aFile.get()); } +# endif #endif #if defined(XP_DARWIN) && !defined(RUST_BINDGEN)