https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61118
Florian Weimer <fw at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|[6/7/8 Regression] Spurious |[6/7/8 Regression] Indirect |-Wclobbered warning |call generated for |generated by gcc 4.9.0 for |pthread_cleanup_push with |pthread_cleanup_push |constant cleanup function --- Comment #13 from Florian Weimer <fw at gcc dot gnu.org> --- This is not simply a spurious warning (the variables in question are only assigned once and their address is not taken, so C semantics do not allow that they are clobbered by setjmp+longjmp). I compiled the reproducer with pthread_cleanup_pop(1); to see the cleanup action on the non-cancellation path, too. All compilation with -fpic to avoid yet another GCC 7 weirdness (movl $cleanup_fn; %eax, call *%rax). GCC 4.8.5 20150623 (Red Hat 4.8.5-22) produces: call pthread_cond_wait@PLT movq %r14, %rdi call __pthread_unregister_cancel@PLT movq %rbx, %rdi call cleanup_fn@PLT GCC 7.2.1 20170829 (Red Hat 7.2.1-1) gives me: movq cleanup_fn@GOTPCREL(%rip), %rax movq %rax, 32(%rsp) … call pthread_cond_wait@PLT movq %rbx, %rdi call __pthread_unregister_cancel@PLT movq 32(%rsp), %rax movq 40(%rsp), %rdi call *%rax This is quite unsatisfying from a security hardening point of view because we now have an unencrypted function pointer on the stack. This situation is somewhat analogous to Windows SEH, which turned out very problematic. (The jmp_buf on the stack isn't ideal, but at least the PC value in it is mangled.)