[Bug middle-end/21161] [6/7/8 Regression] "clobbered by longjmp" warning ignores the data flow

2018-03-05 Thread bruno at clisp dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

--- Comment #15 from Bruno Haible  ---
> I think the following test case does show what Bruno was trying to prove.

Yes, the test case from comment 14 much better reflects what this bug report is
about, than the one from comment 13.

[Bug middle-end/21161] [6/7/8 Regression] "clobbered by longjmp" warning ignores the data flow

2018-03-04 Thread bergner at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

--- Comment #14 from Peter Bergner  ---
(In reply to Peter Bergner from comment #13)
> In case you haven't creduce'd the test case yet, here's what I got:

Of course that's a totally bogus test case given what Bruno was trying to
prove, namely that obj is never updated between the setjmp call and the call to
longjmp, therefor we shouldn't get a warning.  I think the following test case
does show what Bruno was trying to prove.

bergner@pike:~/gcc/BUGS/PR21161$ cat bug.c 
#include 

typedef struct { long a; } * b;
b global_obj;

void
c (b obj)
{
  jmp_buf env;
  if (setjmp(env) != 0)
obj = global_obj;
  if (obj->a)
longjmp (env, 1);
}
bergner@pike:~/gcc/BUGS/PR21161$
/home/bergner/gcc/build/gcc-fsf-mainline-debug/gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-debug/gcc -W -O1 -S bug.c 
bug.c: In function ‘c’:
bug.c:7:6: warning: argument ‘obj’ might be clobbered by ‘longjmp’ or ‘vfork’
[-Wclobbered]
 c (b obj)
~~^~~

[Bug middle-end/21161] [6/7/8 Regression] "clobbered by longjmp" warning ignores the data flow

2018-03-03 Thread bergner at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

Peter Bergner  changed:

   What|Removed |Added

 CC||bergner at gcc dot gnu.org

--- Comment #13 from Peter Bergner  ---
In case you haven't creduce'd the test case yet, here's what I got:

bergner@pike:~/gcc/BUGS/PR21161$ cat pr21161.i
extern int _setjmp (void);
typedef struct { long a; } * b;
extern void d (void);
void
c (b obj)
{
  _setjmp();
  if (((b)0)->a)
obj = 0;
  if (((b)obj)->a)
d();
}
bergner@pike:~/gcc/BUGS/PR21161$
/home/bergner/gcc/build/gcc-fsf-mainline-debug/gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-debug/gcc -W -O1 -S pr21161.i
pr21161.i: In function ‘c’:
pr21161.i:5:6: warning: argument ‘obj’ might be clobbered by ‘longjmp’ or
‘vfork’ [-Wclobbered]
 c (b obj)
~~^~~

[Bug middle-end/21161] [6/7/8 Regression] "clobbered by longjmp" warning ignores the data flow

2018-02-22 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

Jeffrey A. Law  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |law at redhat dot com

--- Comment #12 from Jeffrey A. Law  ---
I've got something that is working on most targets.  I'm still refining a bit,
but I'm pretty confident we'll be able to fix in this cycle.

As expected scanning RTL from the setjmp point to figure out where the longjmp
will go (so that we can use the live-in set at the longjmp target rather than
the live set at the setjmp point) is a bit hairy.

It's almost certainly the case that the scanning is not going to work on all
targets.  For example MIPS inserts an unspec sequence to fiddle the GOT after
the call and I really don't want to ignore an insn we don't understand.  But
again, what I've currently got works on most targets and there's still some
refinements to do to improve coverage.

[Bug middle-end/21161] [6/7/8 Regression] "clobbered by longjmp" warning ignores the data flow

2018-02-20 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

--- Comment #11 from Jeffrey A. Law  ---
Just to record some thoughts.

The implementation of the "clobbered by longjmp" warning essentially looks at
the objects that are live at the setjmp point.  In theory we can do better when
we're dealing with setjmp/sigsetjmp (but not getcontext for example).

In theory we can look at the code after the setjmp for this kind of pattern:

(insn 15 14 21 2 (set (reg:SI 91 [  ])
(reg:SI 0 ax)) "j.c":18 86 {*movsi_internal}
 (expr_list:REG_DEAD (reg:SI 0 ax)
(nil)))
(insn 21 15 22 2 (set (reg:CCZ 17 flags)
(compare:CCZ (reg:SI 91 [  ])
(const_int 0 [0]))) "j.c":18 7 {*cmpsi_ccno_1}
 (nil))
(jump_insn 22 21 23 2 (set (pc)
(if_then_else (eq (reg:CCZ 17 flags)
(const_int 0 [0]))
(label_ref 28)
(pc))) "j.c":18 672 {*jcc}
 (expr_list:REG_DEAD (reg:CCZ 17 flags)
(int_list:REG_BR_PROB 719407028 (nil)))
 -> 28)

Since in the longjmp case, we know this will fallthru, we look at the what's
live-in in the fallthru successor.  If the test were inverted we'd (of course)
look at the live in of the target of the branch.  THat live-in set is what we
want to use to compute setjmp_crosses rather than what's actually live at the
setjmp (which is overly-conservative as it is the union of what's live on both
paths after the setjmp, only one of which we care about).

The implementation would be somewhat gross.  It'd have to account for the
differences between setjmp/sigsetjmp and things like savectx, vfork, and
getcontext.  It might be somewhat fragile since we'd be matching a series of
insns which could look radically different on some targets.  *But* a proof of
concept does seem to work.  I'm going to try to polish that up.

I haven't check if that addresses any of Florian's concerns from 61118. 
There's a reasonable chance it will.

Alternately this could be done on gimple, but I suspect factoring of the
abnormal dispatcher as well as the inaccurate CFG will kill us.

[Bug middle-end/21161] [6/7/8 Regression] "clobbered by longjmp" warning ignores the data flow

2018-01-02 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

Jeffrey A. Law  changed:

   What|Removed |Added

   Target Milestone|--- |8.0