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