[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2021-02-23 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

Martin Sebor  changed:

   What|Removed |Added

   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=22488

--- Comment #9 from Martin Sebor  ---
See pr22488 for the underlying problem with the difference between DECL_SIZE
and TYPE_SIZE of classes with virtual bases.

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-12-01 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

Martin Sebor  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |msebor at gcc dot 
gnu.org
 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #8 from Martin Sebor  ---
Fixed in r11-5628.

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-12-01 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

--- Comment #7 from CVS Commits  ---
The master branch has been updated by Martin Sebor :

https://gcc.gnu.org/g:b76f83e3859f738809d3aa8bd9dc14e10fc40e24

commit r11-5628-gb76f83e3859f738809d3aa8bd9dc14e10fc40e24
Author: Martin Sebor 
Date:   Tue Dec 1 15:10:30 2020 -0700

PR middle-end/97595 - bogus -Wstringop-overflow due to DECL_SIZE_UNIT
underreporting field size

gcc/ChangeLog:

PR middle-end/97595
* tree.c (component_ref_size): Fail when DECL_SIZE != TYPE_SIZE.
* tree.h (DECL_SIZE, TYPE_SIZE): Update comment.

gcc/testsuite/ChangeLog:

PR middle-end/97595
* g++.dg/warn/Warray-bounds-14.C: New test.
* g++.dg/warn/Wstringop-overflow-6.C: New test.

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-12-01 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

Martin Sebor  changed:

   What|Removed |Added

 CC||s...@li-snyder.org

--- Comment #6 from Martin Sebor  ---
*** Bug 98083 has been marked as a duplicate of this bug. ***

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-11-16 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

--- Comment #5 from Jason Merrill  ---
(In reply to Martin Sebor from comment #3)
> 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.

What you're seeing is that the DECL_SIZE of the base subobject excludes any
virtual bases, because they are laid out in the most derived class, while the
TYPE_SIZE of the base type includes them.  CLASSTYPE_SIZE of the base type
should match the DECL_SIZE.

It's definitely OK for a program to refer to a virtual base through any of the
derived classes.

> 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.

So this assumption is invalid for base subobjects of types with virtual bases;
such an offset is only bounded by the most-derived object's size.

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-11-14 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

--- Comment #4 from Martin Sebor  ---
Here's a small test case that causes a bogus false positive with patched GCC
(https://gcc.gnu.org/pipermail/gcc-patches/2020-November/558775.html).

$ cat t.C && gcc -O2 -S -Wall t.C
struct A  { char a[32]; };
struct B: virtual A { };
struct C: B { };

struct D 
{
  B 
  D (B&);
};

D::D (B ): b (b) { }

void f (void*);

void g ()
{
  C c;
  D d (c);
  f ();
}
In constructor ‘D::D(B&)’,
inlined from ‘void g()’ at t.C:18:9:
t.C:11:14: warning: subscript 0 is outside array bounds of ‘B’ [-Warray-bounds]
   11 | D::D (B ): b (b) { }
  |  ^
t.C: In function ‘void g()’:
t.C:3:8: note: source object ‘C::’ of size 8
3 | struct C: B { };
  |^

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-10-28 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|--- |11.0

[Bug tree-optimization/97595] [11 Regression] bogus -Wstringop-overflow due to DECL_SIZE_UNIT underreporting field size

2020-10-27 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97595

Martin Sebor  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  ---
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::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;

   [local count: 1073741824]:
  _1 = _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::_M_cache_locale (_10, _19);
  _20 = &_14->D.42253._M_ios_locale;
  std::basic_ios::_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;

}