On Tue, Oct 11, 2016 at 9:39 AM, Jakub Jelinek wrote: > Here is an attempt to implement C++17 inline variables. > Bootstrapped/regtested on x86_64-linux and i686-linux. > > The main question is if the inline variables, which are vague linkage, > should be !DECL_EXTERNAL or DECL_EXTERNAL DECL_NOT_REALLY_EXTERN while > in the FE. In the patch, they are !DECL_EXTERNAL, except for inline > static data members in instantiated templates. As the inline-var3.C > testcase shows, even if they are !DECL_EXTERNAL (except for the instantiated > static data members), even at -O0 we do not actually emit them unless > odr-used, so to some extent I don't see the point in forcing them to > be DECL_EXTERNAL DECL_NOT_REALLY_EXTERN. Yeah, I ended up agreeing with you. There's no need to work hard to make them work with an obsolete system. So I've checked in the patch with a few minor tweaks, attached. > Another thing is I've noticed (with Jonathan's help to look it up) that > we aren't implementing DR1511, I'm willing to try to implement that, but > as it will need to touch the same spots as the patch, I think it should be > resolved incrementally. Sounds good. > Yet another thing are thread_local inline vars. E.g. on: > struct S { S (); ~S (); }; > struct T { ~T (); }; > int foo (); > thread_local inline S s; > inline thread_local T t; > inline thread_local int u = foo (); > it seems both clang++ (~2 months old) and g++ with the patch emits: > 8 byte TLS _ZGV1{stu] variables > 1 byte TLS __tls_guard variable > and _ZTH1[stu] being aliases to __tls_init, which does essentially: > if (__tls_guard) return; > __tls_guard = 1; > if (*(char *)&_ZGV1s == 0) { > *(char *)&_ZGV1s = 1; > S::S (&s); > __cxa_thread_atexit (S::~S, &s, &__dso_handle); > } > if (*(char *)&_ZGV1t == 0) { > *(char *)&_ZGV1t = 1; > __cxa_thread_atexit (T::~T, &t, &__dso_handle); > } > if (*(char *)&_ZGV1u == 0) { > *(char *)&_ZGV1u = 1; > u = foo (); > } > Is that what we want to emit? At first I doubted this could work properly, > now thinking about it more, perhaps it can. I think so; I don't see a reason for inline vars to work differently from templates here. > And, do we really want all the > _ZGV* vars for the TLS inline vars (and other TLS comdats) to be 8 byte, > even when we are using just a single byte? Or is it too late to change (ABI > break)? Right, the ABI specifies that the guard variable is 8 bytes. A comment says, "The intent of specifying an 8-byte structure for the guard variable, but only describing one byte of its contents, is to allow flexibility in the implementation of the API above. On systems with good small lock support, the second word might be used for a mutex lock. On others, it might identify (as a pointer or index) a more complex lock structure to use." This seems unnecessary for systems with byte atomic instructions, and we might be able to get away with changing it without breaking any actual usage, but it would indeed be an ABI change. > And, as mentioned in the DWARF mailing list, I think we should emit > DW_AT_inline on the inline vars (both explicit and implicit - static > constexpr data members in C++17 mode). I hope that can be done as a > follow-up. Makes sense.