[Toybox] Warning: gcc can't tell this is never used uninitialized, but llvm can.

enh enh at google.com
Tue Oct 30 09:59:38 PDT 2018


On Tue, Oct 30, 2018 at 9:40 AM Rob Landley <rob at landley.net> wrote:
>
> I'm hammering on the release again. I flew back to Austin to vote and took the
> whole week off, so I'm doing toybox and mkroot tidying and tackling some of
> backlog of smaller todo items.
>
> Promoting "watch.c" is currently held up by 2 things: 1) fixing crunch_str() now
> that I know that combining characters are trailing rather than leading (so "this
> is as many characters as will fit on this line" is only detectable when you find
> the first that _won't_, not when you've found the last that _will_.)
>
> And the three warnings gcc produces (but llvm doesn't), the larger todo item for
> which is to figure out what to do about the "int x = x;" stuff, which is where
> gcc produces "may be used uninitialized" warnings for variables that can never
> be used uninitialized, and you can't switch it of without losing the "is used
> uninitialized" warnings which _are_ reliably generated.
>
> The workaround is to initialize it to itself, which doesn't produce any code
> (and thus bloat the resulting binary with useless assignment that are always
> overwritten), but some people complain it's not explicitly covered by the
> standard. (It's clear what it _means_ in C, and Turbo C for DOS back in the
> 1980's was already optimizing it out, but gcc developers go out of their way to
> break "signed integers have had two's complement behavior on every piece of
> hardware manufactured since 1963 and posix requires two's complement be
> available" and "I am comparing two pointers on the same stack to see how much
> stack I've used, but I need to typecast them to long instead of char * because
> gcc"...)
>
> Meanwhile, when I build with the android NDK (which means llvm, I'm not testing
> the NDK's vestigial gcc support that's going away next release anyway),

GCC was removed in r18 already. (there are gcc and g++ wrapper scripts
that just call clang, similar to what Apple did when they moved macOS
over a decade ago, plus GNU binutils is still there for now.)

> it does
> _NOT_ produce spurious warnings:
>
>   $ CROSS_COMPILE=llvm- LDFLAGS=--static make distclean defconfig watch
>   Compile toybox...................llvm-strip: Unknown command line argument
>   '-o'.  Try: '/opt/android/x86_64/bin/llvm-strip -help'
>   llvm-strip: Did you mean '-O'?
>   strip failed, using unstripped
>   .
>
> But of course Ubuntu's gcc still does:
>
>   $ make distclean defconfig watch
>   ...
>   Compile toybox.................toys/pending/watch.c: In function 'watch_main':
>   toys/pending/watch.c:145:8: warning: 'active' may be used uninitialized in
>   this function [-Wmaybe-uninitialized]
>      if (active) {
>         ^
>   toys/pending/watch.c:115:12: warning: 'yy' may be used uninitialized in this
>   function [-Wmaybe-uninitialized]
>          if (yy>=3) xprintf("\r\n");
>             ^
>   toys/pending/watch.c:156:10: warning: 'xx' may be used uninitialized in this
>   function [-Wmaybe-uninitialized]
>        if (xx==width) {
>           ^
>   ...
>
>
> You can search for the "x = x" assignments with the following (although there's
> plenty of false positives):
>
>   grep '[^a-zA-Z0-9]\(..*\) = \1[,; ]' *.c lib/*.c toys/*/*.c
>
> I made a
>
>   #define SHUTUP(x) x = x
>
> And was replacing the assignments with the macro, and in theory you could switch
> them _off_ with a config option if you wanted to debug the compiler, but... is
> anybody likely to do that? It's been broken in gcc for a full decade now. If
> everybody moves to llvm, then it could presumably just be removed.
>
> No, I'm not turning them into initializations to 0. I've inspected them, they're
> all already initialized, this is a BROKEN COMPILER WARNING. Which llvm is not
> producing. The fundamental problem is gcc is doing single variable analysis but
> the warnings are one variable depending on other:
>
>   int a, b;
>
>   a = fruitbasket();
>   if (a) b = potato();
>   ...
>   if (a) printf("%d", b);
>
> Where analysis of A has implications for B but gcc is only ever looking at
> variables in isolation, and then giving wrong answers you can't disable.
>
> Anyway, punting it for this release. I'll probably add the x = x initializations
> to shut up gcc for watch.c when I promote it (llvm doesn't seem to _mind_), but
> in future I think "gcc is crazy, you want llvm" is probably the go-to answer.
>
> We need to add support for all the other architectures to llvm before that's a
> real answer, though. :(
>
> I've cc'd the ellcc maintainer because a reproducible up to date musl toolchain
> with llvm would be kinda nice too.
>
> Rob
>
> P.S. This todo item is very, very old:
>
>   https://landley.net/notes-2006.html#31-12-2006
> _______________________________________________
> Toybox mailing list
> Toybox at lists.landley.net
> http://lists.landley.net/listinfo.cgi/toybox-landley.net



More information about the Toybox mailing list