Re: Problems with -Warray-bounds and -Wstringop-overread

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Sep 21, 2023 at 10:11:34AM +0100, Jonathan Wakely wrote:
> Date: Thu, 21 Sep 2023 10:11:34 +0100
> From: Jonathan Wakely <jwakely.gcc@xxxxxxxxx>
> To: Jochen Topf <jochen@xxxxxxxxxx>
> Cc: gcc-help <gcc-help@xxxxxxxxxxx>
> Subject: Re: Problems with -Warray-bounds and -Wstringop-overread
> 
> On Thu, 21 Sept 2023, 09:27 Jochen Topf, <jochen@xxxxxxxxxx> wrote:
> 
> > Hi!
> >
> > In my C++ code I have been using a pattern to store large and diverse sets
> > of
> > data as follows:
> >
> > * Reserve a block of memory ("the buffer")
> > * Put class X in the beginning of that block (with placement new)
> > * Add extra data after the class in certain formats, for instance lists of
> >   0-terminated strings or lists of (type field, length field, some data)
> > * Repeat with next class X until buffer is full
> >
> > You then know the first instance of class X is at offset 0 in the buffer.
> > The
> > class knows how to access and interpret that extra data beyond its nominal
> > end
> > and it knows how to calculate where the next instance of class X is. So
> > you can
> > access all instance data and iterate over the buffer getting to all the
> > instances of X.
> >
> > If you align everything properly this has always worked well. It means I
> > only
> > need a single memory allocation instead of lots of allocation for bits and
> > pieces and I don't need to store pointers to those bits and pieces, but can
> > derive where they are from the knowledge I have about the structure of
> > those
> > buffers which keeps the data smaller.
> >
> > (In a way this is similar to the pattern of having a zero/one-element
> > array at
> > the end of a struct and storing extra data in that array "beyond the end
> > of the
> > struct", but greatly extended.)
> >
> > Now here is the problem: In the last years GCC has added more and more
> > warnings, specifically -Warray-bounds and -Wstringop-overread that get
> > triggered by my code all over the place because it (understandably) finds
> > that
> > I am accessing stuff outside the class X or some other part of my buffer.
> >
> > I can just disable those warnings, but because that code is in a
> > header-only-library I have to tell every user to disable it or sprinkle my
> > code
> > with pragmas which has its own problems.
> 
> 
> What are the problems with pragmas? That was going to be my suggestion.

I had some bad experiences with pragmas between compilers and compiler
versions not understanding some pragmas which meant I had to wrap them
in other pragmas to disable warnings about pragrams that weren't
understood or shenenigans like that.

But the bigger problem is in this case that they seem to not work in
some of the cases. I am returning raw pointers from lots of functions
and if I wrap those functions in pragmas that does nothing. Only at the
points where those pointers are used, the warning triggers. But that is
not in the library code any more, but in the users code. So if, for
instance, I want to return a "char *" to one of the strings I am storing
in the buffer, that pointer triggers the warning the first time it is
used. I don't know how I can avoid that warning there.

> And because GCC has been adding more
> > of those checks over time (or tightening existing checks) I have more
> > places in
> > my code that trigger those warnings with every GCC release and I fear that
> > will
> > go on.
> >
> > My question are:
> >
> > * Is there something "illegal" (against C++ spec) in what I am doing?
> >
> 
> Only if you don't do it correctly :-)
> 
> * Is there a better way of doing this that avoids triggering those warnings
> >   or to tell the compiler that "I know what I am doing"?
> >
> 
> That's what the pragmas are for.
> 
> It might also be possible to create a compiler firewall with [[gnu::noipa]]
> on some key functions which produce the pointers to the next item in the
> buffer, to stop gcc from analyzing through them.

I just tested this and at least in the one case I tested it, it did
work, getting rid of the warning where the pragma approach didn't. But
reading through the docs it looks like this disables some optimizations
which doesn't sound great to me. And it says " This attribute is
supported mainly for the purpose of testing the compiler." And it feels
strange that a large "hammer" like this is needed to disable a warning.

> > (In case you are interested: The code in question is in the libosmium
> > library
> > https://github.com/osmcode/libosmium and is used in all sorts of software
> > that works with OpenStreetMap data.)
> >
> > Jochen
> > --
> > Jochen Topf  jochen@xxxxxxxxxx  https://www.jochentopf.com/
> > +49-351-31778688
> >

-- 
Jochen Topf  jochen@xxxxxxxxxx  https://www.jochentopf.com/  +49-351-31778688



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux