This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms


On 3/27/19 6:56 PM, Martin Sebor wrote:
On 3/27/19 3:11 PM, Martin Sebor wrote:
On 3/27/19 4:44 AM, Jonathan Wakely wrote:
On 21/03/19 15:03 -0400, Jason Merrill wrote:
On 3/20/19 6:06 PM, Marek Polacek wrote:
On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote:
On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote:
On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote:
On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote:

This test fails with
pr88534.C:58:1: sorry, unimplemented: string literal in function template signature

Interesting...  gcc-8 rejected it with an error message rejecting the template parameter, but my latest trunk build (dated Mar 13, r269641) compiles it all right.  Was there a subsequent fix, maybe?  I didn't
realize it was supposed to be rejected.

Ah, that problem only started with r269814, namely this hunk:

Maybe this is done too early and should be postponed to genericization
(perhaps except for TREE_STATIC vars)?

Or skip when DECL is template_parm_object_p.

Or handle it in mangle.c.  I don't see any reason we shouldn't accept

struct A
{
 char c[4];
};

template <A a> struct B { };
B<A{"FOO"}> b;

Probably we should use the same mangling whether the initializer for c was spelled as a string literal or list of integers.

The thing we still don't want to allow is mangling the *address* of a string literal.

Will that help PR 47488 as well?

What I have (attached) accepts all three test cases from PR 47488
(comment #0, #1, #2, and #5) but with different mangling.

The difference in the mangling of the function in the test case
in comment #0 is

   Clang: _Z1gIiEDTcl1fcvT__ELA1_KcEEERKS0_
   GCC 9: _Z1gIiEDTcl1fcvT__ELKc0EEERKS0_

I'm not very familiar with the C++ ABI mangling but from what
I can tell, Clang treats the type as a literal array of 1 const
char element (LA1_Kc) without actually encoding its value, while
with my patch GCC encodes it as a constant literal initializer
consisting of 1 null char (LKc0).  In other words, Clang would
mangle these two the same for the same T:

   template < typename T >
   decltype (f (T(), "123")) g (const T&);

   template < typename T >
   decltype (f (T(), "abc")) g (const T&);

while GCC would mangle them differently.

Which is correct?  Clang's seems correct in this case but would
it also be correct to mangle Jason's B<A{"FOO"}> the same as
B<A{"BAR"}>?

After some poking around I found the issue below that seems
to answer the question at least for Jason's example:

   https://github.com/itanium-cxx-abi/cxx-abi/issues/64

But this is an open issue that leaves some other questions
unanswered, mainly that of the exact encoding of the literal
(the length of the directly encoded subsequence and the hash
algorithm to compute the hash value of the string).

In any event, using the same encoding as for initializer
lists (i.e., (elt-type, elt-value)...) doesn't follow this
approach.

Should I prototype the solution outlined in the issue for
GCC 9?

I think let's leave that for the future, and use the aggregate encoding for GCC 9.

I suppose there's still the question of compatibility between
initializer lists and string literals, namely whether this

   B<A{"123"}>

is supposed to mangle the same as

   B<A{'1', '2', '3', 0}>

The ABI issue only talks about string literals and not braced
initializer lists.  I see in Revision History [150204] Add
mangling for braced initializer lists, so presumably there
is a difference, but I can't find what it is.

The issue for mangling template arguments of class type is

  https://github.com/itanium-cxx-abi/cxx-abi/issues/63

The mangling of braced-init-lists is

# type {expr-list}, conversion with braced-init-list argument
::= tl <type> <braced-expression>* E

# {expr-list}, braced-init-list in any other context
::= il <braced-expression>* E

Your patch doesn't use this mangling. Here's a variant of my example that actually causes these to show up in the mangling:

struct A { char c[4]; };
template <A a> struct B { };
void f(B<A{"FOO"}>) {}
void g(B<A{'F', 'O', 'O', '\0'}>) {}

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]