On Wed, Aug 23, 2023 at 04:23:00PM -0400, Jason Merrill wrote:
> I'd be surprised if this would affect any real code, but I suppose so. In
> any case I'd like to fix this at the same time as the local statics, to
> avoid changing their mangled name twice.

Ok.
Running now into a problem with abi tags, because cp_maybe_mangle_decomp
is called before the type of the structured binding is finalized (sequence
is cp_maybe_mangle_decomp; cp_finish_decl; cp_finish_decomp), I vaguely
remember the reason was to have the name already mangled by cp_finish_decl
time, so that it can add it into varpool etc..
Will see if I can e.g. pass the initializer expression to
cp_maybe_mangle_decomp and figure out the tags from that.

> > @@ -9049,6 +9050,25 @@ cp_maybe_mangle_decomp (tree decl, tree
> >         tree d = first;
> >         for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
> >     v[count - i - 1] = d;
> > +      if (DECL_FUNCTION_SCOPE_P (decl))
> > +   {
> > +     size_t sz = 3;
> > +     for (unsigned int i = 0; i < count; ++i)
> > +       sz += IDENTIFIER_LENGTH (DECL_NAME (v[i])) + 1;
> > +     char *name = XALLOCAVEC (char, sz);
> > +     name[0] = 'D';
> > +     name[1] = 'C';
> > +     char *p = name + 2;
> > +     for (unsigned int i = 0; i < count; ++i)
> > +       {
> > +         size_t len = IDENTIFIER_LENGTH (DECL_NAME (v[i]));
> > +         *p++ = ' ';
> > +         memcpy (p, IDENTIFIER_POINTER (DECL_NAME (v[i])), len);
> > +         p += len;
> > +       }
> > +     *p = '\0';
> > +     determine_local_discriminator (decl, get_identifier (name));
> > +   }
> 
> Maybe do this in mangle_decomp, based on the actual mangling in process
> instead of this pseudo-mangling?

Not sure that is possible, for 2 reasons:
1) determine_local_discriminator otherwise works on DECL_NAME, not mangled
   names, so if one uses (albeit implementation reserved)
   _ZZN1N3fooI1TB3bazEEivEDC1h1iEB6foobar and similar identifiers, they
   could clash with the counting of the structured bindings
2) seems the local discriminator counting shouldn't take into account
   details like abi tags, e.g. if I have:
struct [[gnu::abi_tag ("foobar")]] S { int a; };
namespace N {
  template <typename T>
  inline int
  foo ()
  {
    static int h = 42; int r = ++h;
    { static S h = { 42 }; r += ++h.a; }
    { static int h = 42; r += ++h; }
    { static S h = { 42 }; r += ++h.a; }
    return r;
  }
}
int (*p) () = N::foo<int>;
  then both GCC and Clang mangle these as
  _ZZN1N3fooIiEEivE1h
  _ZZN1N3fooIiEEivE1hB6foobar_0
  _ZZN1N3fooIiEEivE1h_1
  _ZZN1N3fooIiEEivE1hB6foobar_2
  so whether abi tags appear in the mangled name or not shouldn't result
  in separate buckets for counting.

> 
> > @@ -4564,6 +4519,13 @@ write_guarded_var_name (const tree varia
> >       /* The name of a guard variable for a reference temporary should refer
> >          to the reference, not the temporary.  */
> >       write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
> > +  else if (DECL_DECOMPOSITION_P (variable)
> > +      && DECL_NAME (variable) == NULL_TREE
> > +      && startswith (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)),
> > +                     "_Z"))
> 
> Maybe add a startswith overload that takes an identifier?

Ok.

> > @@ -4630,7 +4592,10 @@ mangle_ref_init_variable (const tree var
> >     start_mangling (variable);
> >     write_string ("_ZGR");
> >     check_abi_tags (variable);
> > -  write_name (variable, /*ignore_local_scope=*/0);
> > +  if (DECL_DECOMPOSITION_P (variable))
> > +    write_guarded_var_name (variable);
> > +  else
> > +    write_name (variable, /*ignore_local_scope=*/0);
> 
> Why not use write_guarded_name unconditionally?

Ok.

        Jakub

Reply via email to