[cxx-abi-dev] Mangling of string literals versus variadic templates

Richard Smith richardsmith at google.com
Tue Dec 17 01:10:07 UTC 2013


Hi,

Consider:

  void g(...);
  template<int...N> inline const char *f() { g("foo" + N ...); return
"bar"; }
  const char *p = f();
  const char *q = f<0>();
  const char *r = f<0, 1>();

In f<>, what is the mangling of the "bar" string literal? Is this the first
string literal or the second?

The ABI document says "In all cases the numbering order is strictly lexical
order based on the original token sequence", but it's not obvious what that
would mean for a template instantiation that discards tokens, as this one
does. Now consider:

  template<int...N> inline const char *h() { g([]{return "foo";}() + N
...); return "bar"; }
  const char *p = h();
  const char *q = h<0>();
  const char *r = h<0, 1>();

What happens here? Does the string literal inside the lambda get a number
in the context of the outer function as well as a number within the lambda?
It appears within the original token sequence...


EDG is the only vendor I can find that provides manglings for string
literals at all, and its results here are surprising. It provides these
manglings for "bar":

  f<>: _ZZ1fIJEEPKcvEs_0
  f<0>: _ZZ1fIJLi0EEEPKcvEs_0
  f<0, 1>: _ZZ1fIJLi0ELi1EEEPKcvEs_0

These suggest that EDG includes "foo" in the numbering, even though it is
not actually part of f<>. But then:

  h<>: _ZZ1hIJEEPKcvEs_0
  h<0>: _ZZ1hIJLi0EEEPKcvEs
  h<0, 1>: _ZZ1hIJLi0ELi1EEEPKcvEs

These seem very surprising. "foo" is included in the numbering *only* in
the case where it doesn't actually appear in the instantiated function body.


Suggestion: change in 5.1.6:

"In all cases the numbering order is strictly lexical order based on the
original token sequence<ins>, excluding any tokens that are part of the
body of a nested entity</ins>. All entities occurring in that sequence are
to be numbered, even if subsequent optimization <ins>or (in the case of a
string literal) expansion of an empty parameter pack</ins> makes some of
them unnecessary."


This would make EDG correct, except for the h<> case, where the mangling
would be _ZZ1hIJEEPKcvEs


Another related issue is with user-defined literals. If 123_x appears in an
inline function, and implicitly calls operator""_x("123"), the implicit
string literal should (presumably) be assigned a mangling number. If it
calls operator"""_x(123ULL), a mangling number should presumably not be
assigned.

Suggestion: insert after previously-quoted text from 5.1.6:

If a user-defined-literal implicitly passes a string literal to a literal
operator, the user-defined-literal token is numbered as if it were a string
literal token.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20131216/df1b5471/attachment.html>


More information about the cxx-abi-dev mailing list