This is an archive of the discontinued LLVM Phabricator instance.

StaticAnalyzer CastToStruct : No memory corruption when casting array to struct
AbandonedPublic

Authored by danielmarjamaki on Sep 5 2016, 8:41 AM.

Details

Reviewers
NoQ
Summary

There is no memory corruption when array is casted to struct (if array is large enough):

int Buf[100];
struct S * P = (struct S *)Buf;

This patch will fix false positives for that. However it does not check if the buffer is large enough. So this patch could cause false negatives.

Diff Detail

Event Timeline

danielmarjamaki retitled this revision from to StaticAnalyzer CastToStruct : No memory corruption when casting array to struct.
danielmarjamaki updated this object.
danielmarjamaki added a reviewer: NoQ.
NoQ edited edge metadata.Sep 9 2016, 12:34 PM
NoQ added a subscriber: cfe-commits.

Adding cfe-commits as per developer policy.

Yeah, it doesn't probably cause the same kind of memory corruption, however i wouldn't call this code safe: it still violates the strict aliasing rule, unless the array is of chars. I think this warning is worth keeping for non-char arrays. Even with -fno-strict-aliasing of some sort, the programmer might run into endianness or alignment issues.

If the -fno-strict-aliasing would fix this warning then it would be OK.

If you are telling me that this CastToStruct check is about alignment or endianness then I think the message is highly misleading. We should rewrite the message.

In general, using char instead of short/int does not prevent alignment/endianness problems as far as I see. You can still have just as many such problems even though array is char.

I am not sure why they did not use char here. But on their platform, sizeof(char)==sizeof(short)==sizeof(int)==1. It does not matter much if a typedef uses char or int.

danielmarjamaki abandoned this revision.Sep 12 2016, 3:32 AM

hmm.. I don't actually care much about this specific check at the moment.

I saw other false positives (unreachable code) and thought that this check made the analyzer think there was corrupted memory.

Now I can't reproduce my other false positives.

I'll close this for now. Unless I get those other FP again I don't care about this.

NoQ added a comment.Sep 12 2016, 8:24 AM

Random thoughts:

  • This checker doesn't alter the exploded graph, so it cannot be causing or suppressing positives in other checkers.
  • We should not be adding platform-specific behavior (eg. working as if sizeof(int) == 1) without actually ensuring that it is so on that platform.
  • As far as i understand, even if sizeof(int) == 1, casting an int * into a structure pointer violates the strict aliasing rule. Simply because int and char are different types, even if they have same size and signedness (note that also char, signed char, unsigned char are three different types, despite two of them refer to the same thing).

In general, using char instead of short/int does not prevent alignment/endianness problems as far as I see.

You're right on this one, it'd only prevent endianness of the buffer ints from causing problems.