Bug 54561 - incorrect setjmp -Wclobber diagnostics
Summary: incorrect setjmp -Wclobber diagnostics
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.7.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2012-09-12 20:53 UTC by Paul Eggert
Modified: 2014-03-19 08:47 UTC (History)
1 user (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

generates incorrect diagnostics with gcc -O2 -Wclobbered (531 bytes, application/octet-stream)
2012-09-12 20:53 UTC, Paul Eggert

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Eggert 2012-09-12 20:53:24 UTC
Created attachment 28180 [details]
generates incorrect diagnostics with gcc -O2 -Wclobbered

If I compile the attached program via the command "gcc -S -Wclobbered
-O2 w.i" (GCC 4.7.1, x86-64, Fedora 17), the output is:

w.i: In function 'png_load_body':
w.i:37:13: warning: variable 'info_ptr' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]
w.i:38:9: warning: variable 'fp' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]

Both warnings are incorrect, because info_ptr and fp are not live
across any possible longjmp.  If longjmp munges these variables,
setjmp must return a nonzero value, and no uses of these variables are
reachable in that case.

Like Bug#48968, I ran into this problem when building Emacs.  This test
case is much shorter, though (I whittled it down), so it should be
easier to debug.
Comment 1 Andrew Pinski 2012-09-12 21:02:37 UTC
Both info_ptr and fp are alive across the setjmp.  GCC does not do fancy detection of alive on one of branches of the result of setjmp.  It just warns if it is alive across on either branch on setjmp.
Comment 2 Paul Eggert 2012-09-12 23:39:16 UTC
> GCC ... warns if it is alive across on either branch on setjmp.

OK, thanks, that's the bug then.  GCC should warn only about the
longjmp branch, not about the non-lonjmp branch.

Can GCC model the longjmp branch as assigning garbage to all the
nonvolatile locals, and then use the algorithm it's already using
when it warns about use of uninitialized locals?  Something like
that should do the trick.
Comment 3 Matthieu Patou 2014-03-19 04:57:28 UTC
I have more issues with Gcc generating wrong warning.
When trying to compile new dissectors with gcc 4.8.8 in wireshark I got:

/home/mat/workspace/wireshark/epan/dissectors/packet-dcerpc-dnsserver.c: In function ‘dnsserver_dissect_struct_DNS_RPC_NAME_LIST’:

/home/mat/workspace/wireshark/epan/dissectors/packet-dcerpc-dnsserver.c:1902:23: warning: variable ‘tmptree’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
  volatile proto_tree *tmptree = NULL;

/home/mat/workspace/wireshark/epan/dissectors/packet-dcerpc-dnsserver.c:1903:23: warning: variable ‘tmpitem’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
  volatile proto_item *tmpitem = NULL;

The manpage of longjmp states that 

"The values of automatic variables are unspecified after a call to longjmp() if they meet all the following criteria:

       ·  they are local to the function that made the corresponding setjmp(3) call;
       ·  their values are changed between the calls to setjmp(3) and longjmp(); and
       ·  they are not declared as volatile."

So without the volatile keyword the warning would valid but I explicitly specified volatile to avoid this warning, unless I mis-understood something I think this warning shouldn't be emitted.
Comment 4 Mikael Pettersson 2014-03-19 08:47:48 UTC
(In reply to Matthieu Patou from comment #3)
>   volatile proto_tree *tmptree = NULL;


    proto_tree * volatile tmptree = NULL;

It's the variable itself that needs to be volatile, not the memory it points to.