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.