[PATCH] D11114: [libcxx] Prefer __nullptr to the current fallback implementation in C++03 to prevent ABI issues.

Eric Fiselier eric at efcs.ca
Fri Jul 10 16:48:48 PDT 2015


EricWF created this revision.
EricWF added a reviewer: mclow.lists.
EricWF added a subscriber: cfe-commits.

The fallback version of nullptr provided by libc++ has a different mangled name than the real thing. This can cause ABI issues between code compiled in C++03 and C++11.  This problem can be fixed when using Clang as the compiler. Clang provides '__nullptr' as an alternate keyword that is available in all C++ dialects. We should prefer using '__nullptr' instead of our own fallback type.

However this change is ABI breaking for any user who already depends the C++03 nullptr_t mangled name. Should we hold this change back until we better understand how to manage ABI changes?

http://reviews.llvm.org/D11114

Files:
  include/__config
  test/std/language.support/support.types/nullptr_t_integral_cast.pass.cpp

Index: test/std/language.support/support.types/nullptr_t_integral_cast.pass.cpp
===================================================================
--- test/std/language.support/support.types/nullptr_t_integral_cast.pass.cpp
+++ test/std/language.support/support.types/nullptr_t_integral_cast.pass.cpp
@@ -7,12 +7,22 @@
 //
 //===----------------------------------------------------------------------===//
 
-// NOTE: nullptr_t emulation cannot handle a reinterpret_cast to an
-// integral type
-// XFAIL: c++98, c++03
-
 // typedef decltype(nullptr) nullptr_t;
 
+// C++ standard:
+//  5.2.10 Reinterpret cast [expr.reinterpret.cast]
+//    p4. A pointer can be explicitly converted to any integral type large enough
+//    to hold it. The mapping function is implementation-defined. [ Note: It is
+//    intended to be unsurprising to those who know the addressing structure of
+//    the underlying machine. — end note ] A value of type std::nullptr_t can be
+//    converted to an integral type; the conversion has the same meaning and
+//    validity as a conversion of (void*)0 to the integral type.
+//    [ Note: A reinterpret_cast cannot be used to convert a value of any type
+//      to the type std::nullptr_t.— end note ]
+
+// NOTE: libc++ provides nullptr_t emulation when 'nullptr' is not provided by
+// the compiler. However there is no way to emulate the reinterpret_cast.
+// UNSUPPORTED: C++98, C++03
 
 #include <cstddef>
 #include <cassert>
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -286,8 +286,12 @@
 #endif
 
 #if !(__has_feature(cxx_nullptr))
+#if !(__is_identifier(__nullptr))
+#define nullptr __nullptr
+#else
 #define _LIBCPP_HAS_NO_NULLPTR
 #endif
+#endif
 
 #if !(__has_feature(cxx_rvalue_references))
 #define _LIBCPP_HAS_NO_RVALUE_REFERENCES


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11114.29504.patch
Type: text/x-patch
Size: 1874 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150710/3a2ee81f/attachment.bin>


More information about the cfe-commits mailing list