On Aug 7, 2013, at 3:26 PM, Richard Smith <[email protected]> wrote:

> One follow-up related to the example that is given above; our UDL mangling 
> produces a slightly different mangled name for this example: 
> _Z1fIiEDTcmclL_Zli2_wPKcELA4_S0_EEfp_ET_, reflecting a difference in the 
> cv-qualification of the type of the argument that is being passed to the 
> literal operator.  Clang's demangled name reflects the use of "char [4]" as 
> the argument type and we're using "const char [4]":
> 
> < decltype(((operator "" _w((char [4])"..."),param#1))) f<int>(T1)
> ---
> > decltype(((operator "" _w((const char [4])"..."),param#1))) f<int>(T1)
> 
> From a Standards point-of-view, we think "const char [4]" is correct here 
> (the call to a raw literal operator X is defined to be equivalent to operator 
> "" X("n"), and the type of "n" is "array of const char").  Is this a clang 
> bug or the result of some implicit conversion (and if so, should it be 
> reflected in the mangling)?
> 
> It looks like this was a transient bug -- I agree that your mangling is the 
> correct one, and it's also the one that Clang trunk produces. 

Thanks for that confirmation.

Another discrepancy seems to be in the use of <unresolved-name> production.  
For example:

  typedef __SIZE_TYPE__ size_t;
  void *operator "" _s(unsigned long long) {}
  void *operator new(size_t) {}
  void *f(unsigned long long) {}
  template<typename T> auto f1(T x)->decltype(operator "" _s(x));
  template<typename T> auto f2(T x)->decltype(operator new(x));
  template<typename T> auto f3(T x)->decltype(f(x));
  int main() {
    f1(0);  // neither g++ nor clang use <unresolved-name> for operator "" _s
            // g++:      _Z2f1IiEDTclli2_sfp_EET_
            // clang:    _Z2f1IiEDTclli2_sfp_EET_
            // expected: _Z2f1IiEDTclonli2_sfp_EET_
    f2(0);  // g++ uses <unresolved-name> for operator new
            // g++:      _Z2f2IiEDTclonnwfp_EET_
            // clang:    _Z2f2IiEDTclnwfp_EET_
            // expected: _Z2f2IiEDTclonnwfp_EET_
    f3(0);  // g++ and clang use <unresolved-name> for f
            // g++:      _Z2f3IiEDTcl1ffp_EET_
            // clang:    _Z2f3IiEDTcl1ffp_EET_
            // expected: _Z2f3IiEDTcl1ffp_EET_
  }

[Mangled names are from g++ 4.8.1 and clang 3.3.]   We believe 
<unresolved-name> should be used for all of these cases.

There's another issue here: demangling the "li" <operator-name>.  Each 
<operator-name> has an implied number of arguments (except the vendor extended 
operator where the number is explicitly supplied), but a literal operator can 
have zero, one or two arguments, so it's not clear which of these applies:

  <expression> ::= <unary operator-name> <expression>
               ::= <binary operator-name> <expression> <expression>

Though GNU cxxfilt (from binutils 2.23) demangles the two names in this example 
properly:

  typedef __SIZE_TYPE__ size_t;
  void operator "" _s(const char *) {}
  void operator "" _s(const char *, size_t) {}
  template<typename T> auto f1(T x)->decltype(operator "" _s(x));
  template<typename T> auto f2(T x)->decltype(operator "" _s(x, 0));
  int main() {
    f1("xyz");  // _Z2f1IPKcEDTclli2_sfp_EET_
    f2("xyz");  // _Z2f2IPKcEDTclli2_sfp_Li0EEET_
  }

Note that if the <unresolved-name> mangling is used here (i.e., with "clonli" 
rather than "clli"), there's no issue with the arguments because 
<unresolved-name> (rather than <unary/binary operator-name>) is used as the 
first argument to the "cl" and the remaining <expressions> are parsed as 
arguments to the "cl" (not the "li").  That's also the case with mangled names 
of the form "clL_Zli2_x..." (where <expr-primary> is used for the first "cl" 
<expression>").

An observation: because the "li" mangling always involves mangling of the 
implicit call to the literal operator, and the "cl" mangling already handles a 
variable number of <expression>s, we need to ensure that the arguments to the 
literal operator are demangled by the "cl" production, not the "li" production; 
i.e., either we don't produce mangled names with "clli" (because 
<unresolved-name> or <expr-primary> should instead be used), or we make a 
special case for "li" that it effectively takes zero <expression> arguments:

        <expression> ::= <nullary operator-name>        # literal operand (no 
arguments)

I'd prefer the first of these options (I haven't seen an example where the 
"clli" mangling makes sense), but I think demanglers need to implement the 
second option in order to deal with existing practice.

Mike Herrick
Edison Design Group
_______________________________________________
cxx-abi-dev mailing list
[email protected]
http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev

Reply via email to