[Bug c++/89579] -Wclobbered warning false positive when compiling with -Og

2019-03-04 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89579

Eric Gallager  changed:

   What|Removed |Added

 CC||egallager at gcc dot gnu.org
 Blocks||82738

--- Comment #3 from Eric Gallager  ---
There's a bunch of other -Wclobbered bugs; is this related to any of them?


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82738
[Bug 82738] [meta-bug] issues with the -Og optimization level

[Bug c++/89579] -Wclobbered warning false positive when compiling with -Og

2019-03-04 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89579

Jeffrey A. Law  changed:

   What|Removed |Added

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

--- Comment #2 from Jeffrey A. Law  ---
I've got some patches in this space that might help.  Essentially we compute an
inaccurate view of lifetime information in the presence of setjmp/longjmp. 
They're a bit gross as they have to deal with the various forms of RTL we can
see between the setjmp point and testing of the return value and I was having
trouble convincing myself of their correctness in one case.  But they're
certainly worth revisiting.

I'm going to assign to myself to do that analysis, but not commit to fixing
(yet) :-)

[Bug c++/89579] -Wclobbered warning false positive when compiling with -Og

2019-03-04 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89579

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org,
   ||law at gcc dot gnu.org,
   ||redi at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek  ---
This is caused by the uninitialized __capacity variable in
basic_string& operator=(basic_string&& __str);

The code is like:
// Just move the allocated pointer, our allocator can free it.
pointer __data = nullptr;
size_type __capacity;
if (!_M_is_local())
  {
if (_Alloc_traits::_S_always_equal())
  {
// __str can reuse our existing storage.
__data = _M_data();
__capacity = _M_allocated_capacity;
  }
else // __str can't use it, so free it.
  _M_destroy(_M_allocated_capacity);
  }

_M_data(__str._M_data());
_M_length(__str.length());
_M_capacity(__str._M_allocated_capacity);
if (__data)
  {
__str._M_data(__data);
__str._M_capacity(__capacity);
  }
else
  __str._M_data(__str._M_local_buf);

Although __capacity is never actually used uninitialized (and e.g. the uninit
warning pass figures that out), because it is used only if __data is non-NULL
and __data is non-NULL only if __capacity is also initialized, with -Og or e.g.
with -O1 -fno-tree-dominator-opts, if we don't perform jump threading, we end
up with something like:
  if (_M_local_buf != _35)
goto ; [70.00%]
  else
goto ; [30.00%]

   [local count: 173485181]:
  __capacity_44 = dummy.D.19123._M_allocated_capacity;

   [local count: 247835973]:
  # __data_47 = PHI <_35(14), 0B(13)>
  # __capacity_48 = PHI <__capacity_44(14), __capacity_50(D)(13)>
  dummy._M_dataplus._M_p = _37;
  _45 = D.24766._M_string_length;
  dummy._M_string_length = _45;
  _46 = D.24766.D.19123._M_allocated_capacity;
  dummy.D.19123._M_allocated_capacity = _46;
  if (__data_47 != 0B)
goto ; [70.00%]
  else
goto ; [30.00%]

   [local count: 173485181]:
  D.24766._M_dataplus._M_p = __data_47;
  D.24766.D.19123._M_allocated_capacity = __capacity_48;
  goto ; [100.00%]

before expansion and later when IRA checks for the clobbered vars, it does:
  if (VAR_P (decl)
  && DECL_RTL_SET_P (decl)
  && REG_P (DECL_RTL (decl))
  && regno_clobbered_at_setjmp (setjmp_crosses, REGNO (DECL_RTL
(decl
where the last one uses:
  return ((REG_N_SETS (regno) > 1
   || REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
   regno))
  && REGNO_REG_SET_P (setjmp_crosses, regno));
While REG_N_SETS is just 1 here for the pseudo used for __capacity, because of
the uninitialized use in the PHI it is considered live on the entry block and
that is why the warning is emitted.

Changing libstdc++ code to size_type __capacity = 0; makes the warning away,
though we'd need to check if it doesn't result in worse generated code.

[Bug c++/89579] -Wclobbered warning false positive when compiling with -Og

2019-03-04 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89579

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-03-04
 Ever confirmed|0   |1