From 676035fe24870a006a2551a59fe2febf82393cad Mon Sep 17 00:00:00 2001 From: Matthieu Martin Date: Tue, 4 Oct 2016 23:28:35 -0700 Subject: [PATCH] Fix optional default initialization Summary: Initialize Optional internal memory, so that "un-initialized memory" tools don't flag its callsites. Reviewed By: yfeldblum Differential Revision: D3960462 fbshipit-source-id: 3bd0109959fb93e040fa2e874f586b3508e46dd2 --- folly/Optional.h | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/folly/Optional.h b/folly/Optional.h index e897c38b..f00a40e1 100644 --- a/folly/Optional.h +++ b/folly/Optional.h @@ -67,17 +67,6 @@ typedef int detail::NoneHelper::*None; const None none = nullptr; -/** - * gcc-4.7 warns about use of uninitialized memory around the use of storage_ - * even though this is explicitly initialized at each point. - */ -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wuninitialized" -# pragma GCC diagnostic ignored "-Wpragmas" -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif // __GNUC__ - class OptionalEmptyException : public std::runtime_error { public: OptionalEmptyException() @@ -273,9 +262,18 @@ class Optional { } struct StorageTriviallyDestructible { - // uninitialized - union { Value value; }; - bool hasValue; + // The union trick allows to initialize the Optional's memory, + // so that compiler/tools don't complain about unitialized memory, + // without actually calling Value's default constructor. + // The rest of the implementation enforces that hasValue/value are + // synchronized. + union { + bool hasValue; + struct { + bool paddingForHasValue_[1]; + Value value; + }; + }; StorageTriviallyDestructible() : hasValue{false} {} @@ -285,12 +283,16 @@ class Optional { }; struct StorageNonTriviallyDestructible { - // uninitialized - union { Value value; }; - bool hasValue; + // See StorageTriviallyDestructible's union + union { + bool hasValue; + struct { + bool paddingForHasValue_[1]; + Value value; + }; + }; StorageNonTriviallyDestructible() : hasValue{false} {} - ~StorageNonTriviallyDestructible() { clear(); } @@ -311,10 +313,6 @@ class Optional { Storage storage_; }; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - template const T* get_pointer(const Optional& opt) { return opt.get_pointer(); -- 2.34.1