[LLVMdev] LTO "bug" and Clang warnings

David Blaikie dblaikie at gmail.com
Tue Jan 8 08:53:43 PST 2013


On Tue, Jan 8, 2013 at 8:16 AM, Renato Golin <renato.golin at linaro.org> wrote:
> After looking at the Livermore for a while, we found the issue that was
> causing LTO to produce a different result.
>
> Consider the code below [1]. setup() doesn't touch bar/baz, main() doesn't
> reference foo. LTO finds, correctly, that it can remove the setup(), but the
> result is different.
>
> The code is clearly wrong,

Pretty sure this is UB. I believe if foo/bar/baz were instead an array
of arrays it might be well defined.

> but the compiler has no right to fix user's
> stupidity, even at that level.

I'm not sure what you mean by "fix user's stupidity" here - could you clarify?

> The only think I can think that would
> mitigate the problem would be to have a warning or out-of-bounds access when
> it's that obvious.

Possible, though I don't think we have anything that goes quite that
far yet (computing the dynamic range of 'i' & checking that it's
beyond the bounds of the array, etc). This seems more like the purview
of the Clang Static Analyzer. Have you tried it to see if it catches
this case?

> Clang folks,
>
> Correct me it I'm wrong, but I humbly think this should be done in the
> front-end, so it's easy to print out line information without requiring
> debug symbols to be present.

Regardless of the technical issues, we generally don't emit any
diagnostics from places other than the front-end for reliability
reasons. You can see this in GCC's optimizer-based warnings: they're
quite unreliable. Subtle changes in code lead to certain
optimizations/analyses not firing & warnings appear/disappear with
relatively little logic/sense to the user.

In short: that option is not something that's ever really considered
for Clang diagnostics.

> How easy would be to do that in Clang's AST?

It's more the proof necessary to compute the bounds of 'i' and access
to the arrays that's the interesting part. Possible, & it wouldn't
surprise me if the SA already does this work, but not something I
think we'd end up doing in clang proper.

> I assume it's only a matter of checking the stride against the bounds of the
> array, if all is knowns at compile time. That would also help against
> segmentation fault.
>
> It wouldn't, however, work with variable length arrays, but VLA tend to
> segfault more often than silently overwrite other global variables.
>
> cheers,
> --renato
>
> [1]
> #include <stdio.h>
>
> struct {
>   int foo[20];
>   int bar[20];
>   int baz[20];
> } S;
>
> void setup() {
>   int i;
>   // OVERWRITES ALL THREE ARRAYS
>   for (i=0; i<60; i++)
>     S.foo[i] = i; // ONLY REFERENCES FOO
> }
>
> // DOESN'T USE FOO
> int main() {
>   int i;
>   setup();
>   printf("Bar: ");
>   for (i=0; i<20; i++)
>     printf("%d ", S.bar[i]);
>   printf("\nBaz: ");
>   for (i=0; i<20; i++)
>     printf("%d ", S.baz[i]);
>   puts("");
>
>   return 0;
> }
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>



More information about the llvm-dev mailing list