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.

Reply via email to