On Thu, Oct 4, 2012 at 8:02 PM, Jason Merrill <ja...@redhat.com> wrote: > On 10/04/2012 01:42 PM, Richard Guenther wrote: >> >> So I suppose the testcase that would be "valid" but break with using >> pure would be instead >> >> int main() >> { >> int x = init_count; >> int *p = get_me(); >> if (init_count == x) >> __builtin_abort(); >> int *q = get_me(); >> if (init_count == x) >> __builtin_abort(); >> } >> >> here when get_me is pure we CSE init_count over the _first_ call of >> get_me. > > > That's OK for C++ thread_local semantics; the initialization is specified to > happen some time before the first use, so the testcase is making an invalid > assumption. This might not be desirable for user-written singleton > functions, though.
Ok, so then let me make another example to try breaking a valid program with the thread_local wrapper being pure: int main() { int &p = get_me(); *p; if (init_count == 1) __builtin_abort(); } note my using of C++ references (which in this case cannot bind to NULL and thus *p might not trap(?)). So the C++ source would be something like thread_local int init_count; int foo () { init_count = 1; return 0; } thread_local int i = foo (); int main() { i; if (init_count != 1) __builtin_abort (); } is that valid? When lowered to the above we would DCE the load of i and the call to the initialization wrapper (because it is pure). Obviously then init_count is no longer 1. Thus my question is - is a valid program allowed to access side-effects of the dynamic TLS initializer by not going through the TLS variable? I realize that's somewhat ill-formed if the TLS variable was a class with a static method doing the access to init_count - using that method would not keep the class instance life. Preventing DCE but not CSE for const/pure functions can be for example done by using the looping-const-or-pure flag (but that also tells the compiler that this function may not return, so it is very specific about the kind of possible side-effect to be preserved). The very specific nature of thread_local TLS init semantics ('somewhen before') is hard to make use of, so if we want to change looping-const-or-pure to something like const-or-pure-with-side-effects we should constrain things more. Richard. > Jason >