On 16/07/16 11:11 +0200, Jakub Jelinek wrote:
On Fri, Jul 15, 2016 at 11:14:03PM +0100, Jonathan Wakely wrote:On 15/07/16 22:53 +0100, Jonathan Wakely wrote: >On 15/07/16 23:36 +0200, Jakub Jelinek wrote: >>On Fri, Jul 15, 2016 at 10:07:03PM +0100, Jonathan Wakely wrote: >>>>+ if (typeid (*this) == typeid(__pointer_type_info)) >>>>+ { >>>>+ *thr_obj = nullptr; >>>>+ return true; >> >>But you have the above store too. > >That doesn't write to the exception object, it only does a single >dereference (compared to the double dereference of the racy write), so >it writes to the local variable in the PERSONALITY_FUNCTION in >eh_personality.cc > >So that shouldn't race with other threads. I think. >TSan agrees. When I compile my test and yours (and include libsupc++/pbase_type_info.cc in the executable, so the writes are also instrumented by tsan) then I see races for the *(ptrdiff_t*)*thr_obj writes but not the *thr_obj ones. It's only the ptr-to-data-member case that scribbles in the actual exception object.In: struct A { int a; }; int a; int main () { try { throw nullptr; } catch (int * const &p) { __builtin_printf ("%p %p\n", p, &p); } try { throw nullptr; } catch (int A::* const &p) { __builtin_printf ("%p\n", &p); asm volatile ("" : : "r" (&p)); } try { throw &a; } catch (int * const &p) { __builtin_printf ("%p %p\n", p, &p); } } I see &p being the address passed to __cxa_throw only in the second case, where does the reference point to in the other two cases? Some temporary in main?
I'm not sure what the difference is there. There's some difference in how pointers and non-pointers are handled.
Does that mean if you rethrow the exception multiple times in different threads you get references to the same object for PMF and to different objects for pointers?
No, for the throw &a case you'll get the same exception object in every thread. say anything about the identity of the caught objects when nullptr is thrown).
