Skip to content

Mangling of structured bindings #152375

@jakubjelinek

Description

@jakubjelinek

Consider

template <typename T>
int
foo ()
{
  static int a = 1, b = 2, c = 3;
  int d = a++ + b++ + c++;
  {
    static int a = 1, b = 2, c = 3;
    d += a++ + b++ + c++;
    {
      static auto [a, b1, b2, b3, c] = T {};
      return a++ + c++ + b2++ + d;
    }
  }
}

struct A { int a, b, c, d, e; };

void
bar ()
{
  foo <A> ();
}

namespace std {
  template<typename T> struct tuple_size;
  template<int, typename> struct tuple_element;
}

struct B {
  int a[5];
  template <int I> int &get () { return a[I]; }
};
         
template<> struct std::tuple_size<B> { static const int value = 5; };
template<int I> struct std::tuple_element<I,B> { using type = int; };

void
baz ()
{
  foo <B> ();
}

E.g. in foo <B>, both clang++ and g++ properly mangle the outermost a, b, c as

_ZZ3fooI1BEivE1{a,b,c}

the one in the next scope
_ZZ3fooI1BEivE1{a,b,c}_0

but then g++ mangles the individual vars in the tuple structured bindings
_ZZ3fooI1BEivE{1a_1,2b1,2b2,2b3,1c_1}

but clang++ mangles those instead
_ZZ3fooI1BEivE{1a.1,2b1,2b2,2b3,1c.1}

I think g++ is right and clang++ is wrong.

Another question is how to mangle structured binding packs.
I've filed itanium-cxx-abi/cxx-abi#200 but nothing happened there.
Testcase would be pretty similar,

template <typename T>
int
foo ()
{
  static int a = 1, b = 2, c = 3;
  int d = a++ + b++ + c++;
  {
    static int a = 1, b = 2, c = 3;
    d += a++ + b++ + c++;
    {
      static auto [a, ...b, c] = T {};
      return a++ + c++ + b...[0]++ + d;
    }
  }
}

struct A { int a, b, c, d, e; };

void
bar ()
{
  foo <A> ();
}

namespace std {
  template<typename T> struct tuple_size;
  template<int, typename> struct tuple_element;
}

struct B {
  int a[5];
  template <int I> int &get () { return a[I]; }
};
         
template<> struct std::tuple_size<B> { static const int value = 5; };
template<int I> struct std::tuple_element<I,B> { using type = int; };

void
baz ()
{
  foo <B> ();
}

One question is whether to somehow show in the whole structured binding mangling that there is a pack in it and where (so one could demangle it as foo<B>()::[a, ...b, c] instead of just foo<B>()::[a, b, c]
And another one what mangling to use for the elements of the structured binding pack.
One possibility is just pretend it is sizeof...(pack) separate instantiations of the local variable (i.e. use b_1, b_2, b_3 in the testcase because b_0 and b_1 were previously used already), or do something else?

@ricejasonf @AaronBallman @cor3ntin

Metadata

Metadata

Assignees

No one assigned

    Labels

    ABIApplication Binary Interfaceclang:frontendLanguage frontend issues, e.g. anything involving "Sema"questionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions