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


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
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to