[cxx-abi-dev] abi_tag mangling

Jason Merrill jason at redhat.com
Mon Aug 1 18:27:52 UTC 2016


On Mon, Jun 27, 2016 at 4:35 PM, Richard Smith <richardsmith at google.com> wrote:
> On 14 June 2016 at 14:09, Jason Merrill <jason at redhat.com> wrote:
>> On Mon, Jun 6, 2016 at 5:29 PM, Richard Smith <richardsmith at google.com> wrote:
>> > On 3 June 2016 at 15:25, Jason Merrill <jason at redhat.com> wrote:
>> >> On Jun 2, 2016, at 3:01 PM, Richard Smith <richardsmith at google.com> wrote:
>> >>
>> >> > If a type is not part of the regular mangling, and it contains an ABI tag in
>> >> > its mangling but not as part of its type (for instance, a dependent
>> >> > expression in a template argument references an entity with an ABI tag),
>> >> > does that appear in the resulting mangling?
>> >>
>> >> > (That is, is an implementation required to effectively mangle the return
>> >> > type and throw it away, or is some walk over the top-level type required
>> >> > instead?)
>> >>
>> >> Hmm, good question.  The current G++ implementation scans dependent
>> >> expressions in a (member function of a class) template, and considers
>> >> those in both the signature and the return type of a non-template
>> >> member function (which is not part of its signature), leading to a
>> >> somewhat curious result for this example:
>> >>
>> >> struct [[gnu::abi_tag ("foo")]] A
>> >> {
>> >>   template <class T> static T f();
>> >> };
>> >>
>> >> template <class T> struct B
>> >> {
>> >>   static decltype(A::f<T>()) g(decltype(A::f<T>()));
>> >>   static decltype(A::f<T>()) h();
>> >> };
>> >>
>> >> int main()
>> >> {
>> >>   B<int>::g(0); // _ZN1BIiE1gEi -- the tag does not appear in the mangled name
>> >>   B<int>::h();  // _ZN1BIiE1hB3fooEv
>> >> }
>> >>
>> >> Here G++ sees that A (and thus tag "foo") appears in the signature of
>> >> B<T>::g, so it doesn't tag B<T>::g, even though the dependent
>> >> expression isn't actually part of the eventual mangling of B<int>::g
>> >> because for non-template member functions we mangle the instantiated
>> >> type rather than the temploid type.  The tag doesn't appear in the
>> >> signature of B<T>::h, so h gets tagged.
>> >
>> > Is that how this is supposed to work, or is it a bug? It would seem more
>> > reasonable to say the tag set added after to the declaration's name is the
>> > tag set from scanning the original unsubstituted declaration, minus the tags
>> > produced by mangling (and I suspect that probably doesn't change the
>> > mangling for any cases in the wild).
>>
>> It does seem like a bug.  For non-template member functions, since the
>> signature we mangle is the fully-instantiated signature, it probably
>> also makes sense to use that signature in determining tags, so that
>> neither of the above functions would mention a tag:
>>
>> struct [[gnu::abi_tag ("foo")]] A
>> {
>>   template <class T> static T f();
>>   template <class T> static A g();
>> };
>>
>> template <class T> struct B
>> {
>>   static decltype(A::f<T>()) fa(decltype(A::f<T>()));
>>   static decltype(A::f<T>()) fv();
>>   static decltype(A::g<T>()) ga(decltype(A::g<T>()));
>>   static decltype(A::g<T>()) gv();
>> };
>>
>> int main()
>> {
>>   B<int>::fa(0);   // _ZN1BIiE2faEi
>>   B<int>::fv();    // _ZN1BIiE2fvEv
>>   B<int>::ga(A()); // _ZN1BIiE2gaE1AB3foo
>>   B<int>::gv();    // _ZN1BIiE2gvB3fooEv
>> }
>>
>> Thoughts?
>
> Seems reasonable to me. This runs the risk of the ABI variance existing only
> in the SFINAE condition, rather than in the signature, but that's probably
> not an issue in practice.

It shouldn't be an issue at all, since SFINAE only applies to member
templates, for which we already mangle the return type, not the above
member functions of a class template.

> Would the upshot then be that the tags are always
> determined as if by mangling the declared return type (after substitution)
> and checking which tags would appear?

Yes.

Did you have a reaction to Dmitry's mail?

Jason


More information about the cxx-abi-dev mailing list