[Bug middle-end/61118] Spurious -Wclobbered warning generated by gcc 4.9.0 for pthread_cleanup_push
eggert at gnu dot org
gcc-bugzilla@gcc.gnu.org
Mon Nov 20 01:19:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61118
Paul Eggert <eggert at gnu dot org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |eggert at gnu dot org
--- Comment #12 from Paul Eggert <eggert at gnu dot org> ---
(In reply to Yuri Gribov from comment #11)
> (In reply to Tavian Barnes from comment #10)
> > > I think it is - __cancel_arg is assigned inside a while loop
> >
> > Specifically a do { } while(0); loop, which obviously has only one iteration.
>
> Actually I was talking about surrounding while
> ((double)future->progress/future->total < progress)...
The variables in question do not survive from one iteration to the next of the
surrounding while loop, so they cannot contribute to a setjmp/longjmp problem.
The code looks like this:
while ((double)future->progress/future->total < progress) {
...
void (*__cancel_routine) (void *) = (cleanup_fn);
void *__cancel_arg = (&future->mutex);
if (__sigsetjmp (((struct __jmp_buf_tag *) (void *)
__cancel_buf.__cancel_jmp_buf),
0)) {
__cancel_routine (__cancel_arg);
...
}
...
}
As the addresses of the locals do not escape and they are never assigned to
after initialization and they do not survive until the next call to
__sigsetjmp, the warnings are false alarms.
Possibly GCC is hoisting the locals out of the loop, incorrectly transforming
the above code into this:
void (*__cancel_routine) (void *);
void *__cancel_arg;
while ((double)future->progress/future->total < progress) {
...
__cancel_routine = (cleanup_fn);
__cancel_arg = (&future->mutex);
if (__sigsetjmp (((struct __jmp_buf_tag *) (void *)
__cancel_buf.__cancel_jmp_buf),
0)) {
__cancel_routine (__cancel_arg);
...
}
...
}
where the warning would be valid.
Also see Bug 48968 which has similar symptoms.
More information about the Gcc-bugs
mailing list