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 3:21 PM Jochen Topf <jochen@xxxxxxxxxx> wrote:
>
> 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.

True. But you can still make it somewhat readable, eg.:

https://github.com/google/highway/blob/master/hwy/ops/x86_128-inl.h#L25-L30

I see you are using cmake as a build tool. You can take advantage of
target_compile_options + PUBLIC to tell your users which flags are
required when consuming your header library.


> 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



-- 
Mathieu




[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