[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-10-10 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|5.5 |6.5

--- Comment #6 from Jakub Jelinek  ---
GCC 5 branch is being closed

[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-07-03 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

Martin Liška  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2017-07-03
  Known to work||4.9.0
Summary|[gcc7 gcc8] |[5/6/7/8 Regression]
   |-fsanitize=thread produce   |-fsanitize=thread produce
   |incorrect -Wreturn-type |incorrect -Wreturn-type
   |warning |warning
 Ever confirmed|0   |1

Richard Biener  changed:

   What|Removed |Added

   Keywords||diagnostic
   Target Milestone|--- |5.5

--- Comment #1 from Martin Liška  ---
Confirmed, started with r219202.

[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-07-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P2

[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-07-25 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

--- Comment #2 from Jakub Jelinek  ---
You get the same thing with any other cleanup, say:
struct C { C (); ~C (); };
int
foo (int a, int b)
{
  C c;
  switch (a)
{
case 0:
  switch (b)
{
default:
  return 0;
}
  break;
default:
  return 0;
}
}
with just -Wreturn-type will warn too.  And no optimizations, with -O1 and
above the eh pass optimizes it away.

[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-07-25 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

--- Comment #3 from Jakub Jelinek  ---
To get rid of the warning just with -fsanitize=threads we could do:
--- gcc/tree-eh.c.jj2017-07-14 13:04:47.0 +0200
+++ gcc/tree-eh.c   2017-07-25 17:09:58.279461377 +0200
@@ -1598,7 +1598,8 @@ decide_copy_try_finally (int ndests, boo
  gimple *stmt = gsi_stmt (gsi);
  if (!is_gimple_debug (stmt)
  && !gimple_clobber_p (stmt)
- && !gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
+ && !gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE)
+ && !gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT))
return false;
}
   return true;

at the expense of (-O0) having more __tsan_func_exit calls but on the other
side perhaps simpler code.
But that doesn't solve the #c2 testcase where we'd warn anyway.
The problem is that for:
  switch (a) , case 0: >
  :
  switch (b) >
  :
  D.2315 = 0;
  return D.2315;
  goto ;
  :
  D.2315 = 0;
  return D.2315;
  :
this ends with a label and thus gimple_seq_may_fallthru returns true, even when
the only goto to that label is dead.  I guess we need to improve switch
expansion for these pathological cases.

[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-07-26 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

Jakub Jelinek  changed:

   What|Removed |Added

 CC||mpolacek at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek  ---
Marek, could we reuse the fallthrough warning infrastructure for this to
determine whether there is a possible fallthrough or not?
Though, trying:
int
foo (int a, int b, int c)
{
  switch (c)
{
case 5:
  switch (a)
{
case 0:
  switch (b)
{
default:
  return 0;
}
  break;
#ifdef FT
case 7:
  break;
#endif
default:
  return 0;
}
case 6:
  return 7;
}
  return 8;
}

we don't warn about the fallthrough from case 5 to case 6 no matter if FT is
defined (in that case there is obvious fallthrough, say for foo (7, 0, 5), or
when FT is not defined (then there isn't, but gimple_seq_may_fallthru doesn't
know that).  Whether a label is emitted after a switch (for the break; label)
is determined already in the FEs based on whether any break; is present, no
matter if reachable or not.  So indeed, dead code such as the break; in your
#c0 testcase, or whatever other code followed by a break, is able to confuse
the gimplifier and eh lowering into assuming there might be fallthrough.
While the -Wreturn-type warning is emitted after cfg is built, the problem is
if we decide to emit the try/finally with a finally_tmp variable to avoid
duplicating the cleanup actions, then while after building cfg we optimize away
obviously unreachable code, we have no SSA form yet and thus determining if the
finally_tmp.N variable is always the same in all paths might be expensive.
At -O0 that actually isn't optimized by anything until assembly is emited, so
we still see in the assembly:
testl   %eax, %eax
jne .L9
movl$0, %ebx
movl$0, %r12d
jmp .L4
.L9:
movl$0, %ebx
movl$0, %r12d
.L4:
// Here both %ebx and %r12d are 0 (set the same on both paths reaching this
// label.
leaq-17(%rbp), %rax
movq%rax, %rdi
// Here we run ~C()
call_ZN1CD1Ev
// Now we test whether it is 1, which is never, in that case we fall through
// into returning without a value.
cmpl$1, %r12d
jne .L10
nop
jmp .L1
.L10:
movl%ebx, %eax
.L1:
addq$32, %rsp
popq%rbx
popq%r12
popq%rbp
ret

So, if we can't do anyuthing for this at the gimplifier level, we'd need to add
an optimization in the cfg pass that would look for cases like:
;;   basic block 4, loop depth 0
;;pred:   3
 [0.00%] [count: INV]:
  D.2315 = 0;
  finally_tmp.0 = 0;
  goto ; [INV] [count: INV]
;;succ:   6

;;   basic block 5, loop depth 0
;;pred:   3
 [0.00%] [count: INV]:
  D.2315 = 0;
  finally_tmp.0 = 0;
;;succ:   6

;;   basic block 6, loop depth 0
;;pred:   4
;;5
  C::~C (&c);
  switch (finally_tmp.0)  [INV] [count: INV], case 1:  [INV]
[count: INV]>
and optimize that switch into goto ; after checking that finally_tmp.0 var
is not addressable, not modified in the bb with the switch and set to the same
value at the end of all predecessor bbs.
But that would be an optimization, not sure if we want to do that generally for
-O0, or limit it to somehow specially marked finally_tmp.NN variables.

[Bug sanitizer/81275] [5/6/7/8 Regression] -fsanitize=thread produce incorrect -Wreturn-type warning

2017-07-26 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81275

--- Comment #5 from Marek Polacek  ---
(In reply to Jakub Jelinek from comment #4)
> Marek, could we reuse the fallthrough warning infrastructure for this to
> determine whether there is a possible fallthrough or not?
> Though, trying:
> int
> foo (int a, int b, int c)
> {
>   switch (c)
> {
> case 5:
>   switch (a)
>   {
>   case 0:
> switch (b)
>   {
>   default:
> return 0;
>   }
> break;
> #ifdef FT
>   case 7:
> break;
> #endif
>   default:
> return 0;
>   }
> case 6:
>   return 7;
> }
>   return 8;
> }
> 
> we don't warn about the fallthrough from case 5 to case 6 no matter if FT is
> defined (in that case there is obvious fallthrough, say for foo (7, 0, 5), or
> when FT is not defined (then there isn't, but gimple_seq_may_fallthru
> doesn't know that).  

Unfortunately, not yet, because -Wimplicit-fallthrough doesn't scan nested
switches (PR79153).