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.