diff options
author | Jeffrey Walton <noloader@gmail.com> | 2015-08-02 02:11:46 -0400 |
---|---|---|
committer | Jeffrey Walton <noloader@gmail.com> | 2015-08-02 02:11:46 -0400 |
commit | 24047196b10186d370462b9725a6a950793bc930 (patch) | |
tree | 51031fc37783c14d642d8b5980d77f1481176bdd /smartptr.h | |
parent | b44546be11c235c108a97c798fd6602c7cdaa400 (diff) | |
download | cryptopp-git-24047196b10186d370462b9725a6a950793bc930.tar.gz |
Cleaned up code to tame the optimizer in smart_ptr and member_ptr. It should work on all platforms
Diffstat (limited to 'smartptr.h')
-rw-r--r-- | smartptr.h | 35 |
1 files changed, 10 insertions, 25 deletions
@@ -7,24 +7,8 @@ NAMESPACE_BEGIN(CryptoPP) -// Hack ahead. Apple's standard library does not have C++'s unique_ptr in C++11. We can't -// test for unique_ptr directly because some of the non-Apple Clangs on OS X fail the same -// way. However, modern standard libraries have <forward_list>, so we test for it instead. -// Thanks to Jonathan Wakely for devising the clever test for modern/ancient versions. -// Visual Studio did not add template aliases until VS 2015 (v19.00). Compile failed under -// Visual Studio 2010 (v16.00) and Visual Studio 2012 (v17.00). -#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900) -# if defined(__clang__) -# if (__has_include(<forward_list>)) -# define CRYPTOPP_HAVE_UNIQUE_PTR 1 -# endif -# else -# define CRYPTOPP_HAVE_UNIQUE_PTR 1 -# endif -#endif - -// The result of below is a CryptoPP::auto_ptr in both cases -#ifdef CRYPTOPP_HAVE_UNIQUE_PTR +// CryptoPP::auto_ptr in created in both cases +#if defined(CRYPTOPP_CXX11_UNIQUE_PTR) && defined(CRYPTOPP_CXX11_TEMPLATE_ALIAS) template<typename T> using auto_ptr = std::unique_ptr<T>; #else @@ -49,11 +33,14 @@ private: template <class T> simple_ptr<T>::~simple_ptr() { delete m_p; - m_p = NULL; - + *((volatile T**)(&m_p)) = 0; + + // Ensure the assignment is always performed. MSVC and Clang provide expected + // operational behavior for volatile. GCC has a more strict interpretation of + // the keyword (see http://www.airs.com/blog/archives/154), and volatile + // should not be used to tame the optimizer. However, inline assembly + // will tame it (see https://gcc.gnu.org/ml/gcc-help/2015-07/msg00053.html). #ifdef __GNUC__ - // From Andrew Haley (GCC Dev), to tame the optimizer so the assignment is always performed. - // See "Disable optimizations in one function" on the GCC mailing list. asm volatile ("" : : : "memory"); #endif } @@ -77,12 +64,10 @@ public: T* release() { T *old_p = m_p; - m_p = 0; + *((volatile T**)(&m_p)) = 0; return old_p; #ifdef __GNUC__ - // From Andrew Haley (GCC Dev), to tame the optimizer so the assignment is always performed. - // See "Disable optimizations in one function" on the GCC mailing list. asm volatile ("" : : : "memory"); #endif } |