Giter VIP home page Giter VIP logo

Comments (12)

daveedvdv avatar daveedvdv commented on July 20, 2024

from cxx-abi.

zygoloid avatar zygoloid commented on July 20, 2024

See also issue #64 for mangling string literals. We should consider whether there's a generalized technique for hashing large objects that we can share between that and this. In this case, an additional complication is that we don't necessarily have a concrete value -- pointer subobjects of the non-type template argument value need to be encoded symbolically. Perhaps we could (in both cases) compute the full mangling and then reduce it to a prefix and a hash if it's longer than some threshold.

from cxx-abi.

jicama avatar jicama commented on July 20, 2024

And when a string is used to initialize a member of character array type, it should be mangled the same as that member initialized by a braced-init-list, since the semantic effect is the same. That is, for

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

The types of f and g are the same, and should mangle the same.

from cxx-abi.

zygoloid avatar zygoloid commented on July 20, 2024

We are guaranteed that such classes are not unions and do not contain unions

This is no longer the case; presumably using a designated initialization mangling to identify the active member would be reasonable. This leaves open the question of how to mangle a union with no active member. tl1UE (U{}) would be available for this use but doesn't really seem "right". Maybe Li1UE?

from cxx-abi.

zygoloid avatar zygoloid commented on July 20, 2024

GCC has implemented some variant of this proposal. Specifically:

  • They appear to use tl <type> <expression>* E for classes, but drop some trailing elements.
  • They appear to use tl <type> di <source-name> <expression>* E for unions.
  • They appear to use tl <type> <expression>* E for arrays, but unpredictably[1] drop some (but not all) trailing elements that are the same as a zero-initialized element.
  • References to subobjects are mangled using dt, ix, but derived-to-base conversions are not mangled resulting in collisions[2].
  • Pointers to subobjects are mangled as ad + a reference expression.
  • Pointers-to-data-members are sometimes mangled as offsets (LM1Xi0E), sometimes as an "address-of" operation (adL_ZN1B1nEE).
  • Pointers-to-member-functions are mangled as structs (tlM1BFivEadL_ZNS1_1nEvEE).
  • The template parameter object itself uses the proposed _ZTAX...E mangling.

I'd suggest we make the following modifications to that scheme before adopting it:

1: Use L <type> E to represent uninitialized objects and unions with no active member. (GCC doesn't appear to support these in template arguments yet.)
2: Omit trailing elements from the three tl manglings if and only if every scalar subobject is initialized to zero and every union with members has its first member active.
3: Use the scheme in #47 for pointers, references, and pointers-to-members. In particular, disambiguate references to base members where necessary, and mangle pointers-to-members semantically rather than (sometimes) based on the generated constant value.

[1]:

union Q { int n, m; constexpr Q(int k) : n(k) {} constexpr Q() : n(0) {} };
struct A { Q arr[6]; };
template<A a> struct B {};

// Mangled as _Z1f1BIXtl1AtlA6_1QtlS1_di1nLi1EEtlS1_di1nLi2EEtlS1_di1nLi3EEtlS1_di1nLi0EEEEEE
// Note that Q(0) element is mangled but Q() elements are not.
void f(B<A{1, 2, 3, 0}>) {}

[2]:

struct A { int n; };
struct B : A { int n; } b;

struct D { int &r; };
template<D> int x;
// These different variables mangle the same.
int &y = x<D{b.A::n}>;
int &z = x<D{b.B::n}>;

from cxx-abi.

zygoloid avatar zygoloid commented on July 20, 2024

When mangling a class member, GCC appears to remove top-level cv-qualifiers. Example:

struct A { const int a; int *const b; int c; };
template<A> void f() {}
template void f<A{.c = 1}>();

... is mangled as _Z1fIXtl1ALi0ELPi0ELi1EEEEvv, not as _Z1fIXtl1ALKi0ELKPi0ELi1EEEEvv. It seems reasonable to follow that; the cv-qualifiers are irrelevant to the value.

from cxx-abi.

rjmccall avatar rjmccall commented on July 20, 2024

Notes from writing this up:

  • Is it actually possible to have an uninitialized field of a class, other than as a union with no active member?
  • It's a little unfortunate that we have to write the type of the active member of a union when writing its initializer. The case that would be nice to optimize here is when it's a class type, because we could just use li.
  • There seems to be a truly awful special case with trivial anonymous unions where we need to name the type in order to say that it doesn't have an active member but we can't name it because it doesn't have any named members.

Anyway, I have a draft up as #140

from cxx-abi.

jensmaurer avatar jensmaurer commented on July 20, 2024

Is it actually possible to have an uninitialized field of a class, other than as a union with no active member?

In general, the answer is "yes" (of course), but I think the question is for constant values (template arguments) only. See core issue 2536 and 2558:

https://cplusplus.github.io/CWG/issues/2536.html
https://cplusplus.github.io/CWG/issues/2558.html

from cxx-abi.

rjmccall avatar rjmccall commented on July 20, 2024

Right, I just mean whether such values are allowed as constants, because Richard's write-up covered them but I couldn't convince a compiler to allow it. It sounds like the resolution is that they're not allowed? (I'm somewhat surprised that the resolution wasn't that they're zero-initialized.)

from cxx-abi.

jensmaurer avatar jensmaurer commented on July 20, 2024

Those core issues have been created, but have not yet been discussed in a CWG meeting. Anything can still happen here.

from cxx-abi.

zygoloid avatar zygoloid commented on July 20, 2024

Before we consider this settled, we should also consider #64. It might be a good idea to use that kind of mangling approach for char arrays in template argument values as well as for string literals.

from cxx-abi.

rjmccall avatar rjmccall commented on July 20, 2024

I'm now addressing this (but not the string-literal question Richard raised above) in #166.

from cxx-abi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.