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

            Bug ID: 123800
           Summary: Speculative devirt for multiple targets causes
                    -Warray-bounds false positive: since r16-4000
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: siddhesh at gcc dot gnu.org
  Target Milestone: ---

This was seen when building 7zip:

https://koji.fedoraproject.org/koji/taskinfo?taskID=141135824

$ cat > ContHandler.C

struct IUnknown {
  virtual unsigned Release();
};
template <class T> struct CMyComPtr {
  T *_p;
  CMyComPtr(T *p) { _p = p; }
  ~CMyComPtr() {
    if (_p)
      _p->Release();
  }
};
struct CMyUnknownImp {
  int _m_RefCount;
};
struct CLocalProgress final : IUnknown, CMyUnknownImp {
  unsigned Release() {
    delete this;
    return 0;
  }
  CMyComPtr<IUnknown> _ratioProgress;
  long ProgressOffset;
  long OutSize;
};
struct CHandlerImgProgress : IUnknown, CMyUnknownImp {
  int QueryInterface;
  int Handler;
  CMyComPtr<int> _ratioProgress;
  CHandlerImgProgress();
};
void CHandlerImgExtract() {
  CHandlerImgProgress *imgProgressSpec = new CHandlerImgProgress;
  CMyComPtr<IUnknown> imgProgress = imgProgressSpec;
}

$ gcc/cc1plus -O2 -Wall -quiet -o /dev/null HandlerCont.C
In destructor ‘CLocalProgress::~CLocalProgress()’,
    inlined from ‘virtual unsigned int CLocalProgress::Release()’ at
HandlerCont.C:17:12,
    inlined from ‘CMyComPtr<T>::~CMyComPtr() [with T = IUnknown]’ at
HandlerCont.C:9:18,
    inlined from ‘void CHandlerImgExtract()’ at HandlerCont.C:33:1:
HandlerCont.C:15:8: warning: array subscript ‘CLocalProgress[0]’ is partly
outside array bounds of ‘unsigned char [32]’ [-Warray-bounds=]
   15 | struct CLocalProgress final : IUnknown, CMyUnknownImp {
      |        ^~~~~~~~~~~~~~
HandlerCont.C: In function ‘void CHandlerImgExtract()’:
HandlerCont.C:31:46: note: object of size 32 allocated by ‘operator new’
   31 |   CHandlerImgProgress *imgProgressSpec = new CHandlerImgProgress;
      |                                              ^~~~~~~~~~~~~~~~~~~

The warning obviously goes away with --param max-devirt-targets=1.

Reply via email to