https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org
            Summary|[11 Regression] warning:    |[11 Regression] bogus
                   |writing 1 byte into a       |-Wstringop-overflow due to
                   |region of size 0            |DECL_SIZE_UNIT
                   |[-Wstringop-overflow=]      |underreporting field size
           Keywords|                            |diagnostic
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2020-10-27

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
I can confirm the warning but I'm not sure the bug is in the middle end code. 
Let me CC Jason for his comments.

The warning triggers for the MEM_REF below:

  MEM[(char &)_10 + 224] = _24;

in the following GIMPLE ("type" is char).  The destination of the access is
this_3(D)->D.45669 which is the basic_istream subobject.  Its size reported by
DECL_SIZE_UNIT() in component_ref_size() is 16.  The initial offset (i.e., _10)
is indeterminate but it's taken to be in the range bounded by the size of the
object, or [0, 16].  Given that, the constant offset 224 is determined to be
out of bounds.

The change introduced in r11-3827 that triggers the warning is the assumption
that unless determined otherwise, an indeterminate offset into an object must
be bounded by the object's size.

But sizeof (basic_istream) is 280, not 16.  This is also what TYPE_SIZE_UNIT()
reports, so the bug here is either in DECL_SIZE_UNIT(), or in using it in lieu
of TYPE_SIZE_UNIT().  I'd expect the two to return the same result so this
seems like a front end bug to me but I will defer to Jason.

std::basic_iostream<char>::swap (struct basic_iostream * const this, struct
basic_iostream & __rhs)
{
  struct basic_istream * _1;
  struct basic_istream * _2;
  int (*) () * _7;
  long int _8;
  sizetype _9;
  struct basic_ios * _10;
  int (*) () * _11;
  long int _12;
  sizetype _13;
  struct basic_ios & _14;
  long int _15;
  long int _16;
  struct ios_base * _17;
  struct ios_base * _18;
  struct locale * _19;
  struct locale * _20;
  struct basic_ostream * _21;
  struct basic_ostream * _22;
  char _23;
  char _24;
  bool _25;
  bool _26;

  <bb 2> [local count: 1073741824]:
  _1 = &this_3(D)->D.45669;
  _2 = &__rhs_4(D)->D.45669;
  _7 = MEM[(struct basic_istream *)this_3(D)]._vptr.basic_istream;
  _8 = MEM[(long int *)_7 + -24B];
  _9 = (sizetype) _8;
  _10 = _1 + _9;
  _11 = MEM[(struct basic_istream *)__rhs_4(D)]._vptr.basic_istream;
  _12 = MEM[(long int *)_11 + -24B];
  _13 = (sizetype) _12;
  _14 = _2 + _13;
  _17 = &_10->D.42253;
  _18 = &_14->D.42253;
  std::ios_base::_M_swap (_17, _18);
  _19 = &_10->D.42253._M_ios_locale;
  std::basic_ios<char>::_M_cache_locale (_10, _19);
  _20 = &_14->D.42253._M_ios_locale;
  std::basic_ios<char>::_M_cache_locale (_14, _20);
  _21 = MEM[(struct basic_ostream * &)_10 + 216];
  _22 = MEM[(struct basic_ostream * &)_14 + 216];
  MEM[(struct basic_ostream * &)_10 + 216] = _22;
  MEM[(struct basic_ostream * &)_14 + 216] = _21;
  _23 = MEM[(type &)_10 + 224];                        <<< -Wstringop-overflow
  _24 = MEM[(type &)_14 + 224];
  MEM[(char &)_10 + 224] = _24;
  MEM[(char &)_14 + 224] = _23;
  _25 = MEM[(type &)_10 + 225];
  _26 = MEM[(type &)_14 + 225];
  MEM[(bool &)_10 + 225] = _26;
  MEM[(bool &)_14 + 225] = _25;
  _15 = MEM[(type &)this_3(D) + 8];
  _16 = MEM[(type &)__rhs_4(D) + 8];
  MEM[(long int &)this_3(D) + 8] = _16;
  MEM[(long int &)__rhs_4(D) + 8] = _15;
  return;

}

Reply via email to