summaryrefslogtreecommitdiff
path: root/smartptr.h
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2015-08-02 02:11:46 -0400
committerJeffrey Walton <noloader@gmail.com>2015-08-02 02:11:46 -0400
commit24047196b10186d370462b9725a6a950793bc930 (patch)
tree51031fc37783c14d642d8b5980d77f1481176bdd /smartptr.h
parentb44546be11c235c108a97c798fd6602c7cdaa400 (diff)
downloadcryptopp-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.h35
1 files changed, 10 insertions, 25 deletions
diff --git a/smartptr.h b/smartptr.h
index 057f5213..909afd07 100644
--- a/smartptr.h
+++ b/smartptr.h
@@ -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
}