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

            Bug ID: 102101
           Summary: Another spurious -Warray-bounds
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sbergman at redhat dot com
                CC: msebor at gcc dot gnu.org
  Target Milestone: ---

On recent trunk (basepoints/gcc-12-3135-gdb3d4129b6f):

> $ cat test.cc
> #include <cstddef>
> #include <vector>
> long dummy();
> void * rtl_allocateMemory();
> struct XInterface {
>     virtual void acquire() = 0;
>     void release();
> };
> struct WeakComponentImplHelperBase: XInterface {
>     static void * operator new(std::size_t) { return rtl_allocateMemory(); }
>     static void operator delete(void *);
>     virtual void acquire();
> };
> struct XPrimitive2D: XInterface {};
> struct PartialWeakComponentImplHelper: WeakComponentImplHelperBase, 
> XPrimitive2D {
>     void acquire() { WeakComponentImplHelperBase::acquire(); }
> };
> struct FillHatchPrimitive2D: PartialWeakComponentImplHelper {
>     FillHatchPrimitive2D();
> };
> struct Reference {
>     XInterface * _pInterface;
>     ~Reference() { if (_pInterface) _pInterface->release(); }
>     Reference(XPrimitive2D * pInterface) {
>         _pInterface = static_cast<XInterface *>(static_cast<void 
> *>(pInterface));
>         if (_pInterface) _pInterface->acquire();
>     }
> };
> struct Size {
>     Size();
>     bool IsEmpty() const { return nA || nB; }
>     int nA, nB;
> };
> struct PropertyHolder {
>     bool getLineOrFillActive() { return mbLineColor || mbFillColor; }
>     bool mbLineColor, mbFillColor;
> };
> struct NonOverlappingFillGradientPrimitive2D: FillHatchPrimitive2D {
>     void create2DDecomposition() { if (dummy()) dummy(); }
>     NonOverlappingFillGradientPrimitive2D() {}
> };
> void implInterpretMetafile(PropertyHolder & rPropertyHolders) {
>     int nCount = dummy();
>     int nAction = 0;
>     switch(dummy()) {
>     case 0:
>         while (0 == dummy() && nAction < nCount) {}
>     case 1:
>         while (0 == dummy() && nAction < nCount) {}
>     case 2:
>         if (rPropertyHolders.getLineOrFillActive()) {
>             Size rRectangle;
>             if (rRectangle.IsEmpty()) {
>                 Size aRange;
>                 if (aRange.IsEmpty()) dummy();
>             }
>         }
>     case 3:
>         if (rPropertyHolders.getLineOrFillActive()) {
>             Size rRectangle;
>             if (rRectangle.IsEmpty()) {
>                 Size aRange;
>                 if (aRange.IsEmpty()) dummy();
>             }
>         }
>     case 4:
>         if (rPropertyHolders.getLineOrFillActive()) {
>             Size rRectangle;
>             if (rRectangle.IsEmpty()) {
>                 Size aRange;
>                 if (aRange.IsEmpty()) dummy();
>             }
>         }
>     case 5:
>         if (rPropertyHolders.getLineOrFillActive()) {
>             Size rRectangle;
>             if (rRectangle.IsEmpty()) {
>                 Size aRange;
>                 if (aRange.IsEmpty()) dummy();
>             }
>         }
>     case 6:
>         if (rPropertyHolders.getLineOrFillActive()) {
>             Size rRectangle;
>             if (rRectangle.IsEmpty()) {
>                 Size aRange;
>                 if (aRange.IsEmpty()) dummy();
>             }
>         }
>     case 7:
>         if (rPropertyHolders.getLineOrFillActive()) dummy();
>     case 8:
>         if (rPropertyHolders.getLineOrFillActive()) dummy();
>     case 9:
>         if (rPropertyHolders.getLineOrFillActive()) dummy();
>     case 10:
>         if (rPropertyHolders.getLineOrFillActive()) dummy();
>     case 11:
>         if (rPropertyHolders.getLineOrFillActive()) dummy();
>     case 12:
>         {
>             int nTextLength = dummy();
>             int nTextIndex = dummy();
>             int nStringLength = dummy();
>             if (nTextLength + nTextIndex > nStringLength) {
>                 nTextLength = nTextIndex > nStringLength ? 0 : nStringLength 
> - nTextIndex;
>             }
>             if (nTextLength && dummy()) {
>                 std::vector< double > aDXArray;
>                 aDXArray.reserve(nTextLength);
>             }
>         }
>     case 13:
>         if (dummy() && dummy())
>             if (dummy() && dummy()) dummy();
>     case 14:
>         {
>             Size rRectangle;
>             if (rRectangle.IsEmpty() && dummy()) dummy();
>         }
>     case 15:
>         Reference(new FillHatchPrimitive2D);
>     }
> }

> $ g++ -D_GLIBCXX_DEBUG -Werror -Warray-bounds -O2 -c test.cc
> In member function ‘virtual void PartialWeakComponentImplHelper::acquire()’,
>     inlined from ‘Reference::Reference(XPrimitive2D*)’ at test.cc:26:46,
>     inlined from ‘void implInterpretMetafile(PropertyHolder&)’ at 
> test.cc:122:9:
> test.cc:16:58: error: array subscript 0 is outside array bounds of 
> ‘XPrimitive2D [1152921504606846975]’ [-Werror=array-bounds]
>    16 |     void acquire() { WeakComponentImplHelperBase::acquire(); }
>       |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
> test.cc: In function ‘void implInterpretMetafile(PropertyHolder&)’:
> test.cc:15:8: note: at offset -8 into object 
> ‘PartialWeakComponentImplHelper::<anonymous>’ of size 8
>    15 | struct PartialWeakComponentImplHelper: WeakComponentImplHelperBase, 
> XPrimitive2D {
>       |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> cc1plus: all warnings being treated as errors

(The test code only fails with the _GLIBCXX_DEBUG version of <vector>, which is
probably just another random coincidental part of this reproducer, and I didn't
feel like trying to minimize it even further.)

Reply via email to