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?