https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91979
Bug ID: 91979 Summary: Incorrect mangling for non-template-argument nullptr expression Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jrtc27 at jrtc27 dot com Target Milestone: --- Consider the mangling for the following code: ``` template <bool, typename T = void> struct enable_if {}; template <typename T> struct enable_if<true, T> { typedef T type; }; template <void *P> void foo(typename enable_if<P == nullptr>::type* = 0) {} template void foo<(void *)0>(void *); ``` This is one way of exposing how the expression `nullptr` is mangled when of type nullptr_t. Currently, GCC produces: _Z3fooILPv0EEvPN9enable_ifIXeqT_LDn0EEvE4typeE whereas Clang produces: _Z3fooILPv0EEvPN9enable_ifIXeqT_LDnEEvE4typeE Note the difference between LDn0E and LDnE for representing the nullptr inside the boolean expression for the enable_if. Based on the specification in cxx-abi, Clang is correct: > The pointer literal expression nullptr is encoded as "LDnE". In contrast, a > template > argument which happens to be a null pointer (an extension made standard in > C++11) is > mangled as if it were a literal 0 of the appropriate pointer type; for > example, > "LPi0E" or "LDn0E". This inconsistency is an unfortunate accident. The bug is in cp/mangle.c write_expression: ``` /* Handle literals. */ else if (TREE_CODE_CLASS (code) == tcc_constant || code == CONST_DECL) write_template_arg_literal (expr); ``` This is correct for literal expressions, which are mangled identically to template argument literals, with the exception of nullptr. Note also that c++filt (and thus GCC's/libiberty's demangler) does not Clang's compliant mangling, only GCC's current incorrect mangling.