diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2016-04-25 14:44:25 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2016-04-25 14:44:25 +0000 |
commit | 70247e69b1f1fde7f11b6cd81bc50162f9b79ab2 (patch) | |
tree | c562c6bc4b43624c42b4ecbb8c562048ec2ffa52 /clang/test/Analysis/call-invalidation.cpp | |
parent | dd215236530c9f643220f1c6e928dd39254a7b3d (diff) | |
download | bcm5719-llvm-70247e69b1f1fde7f11b6cd81bc50162f9b79ab2.tar.gz bcm5719-llvm-70247e69b1f1fde7f11b6cd81bc50162f9b79ab2.zip |
[analyzer] Let TK_PreserveContents span across the whole base region.
If an address of a field is passed through a const pointer,
the whole structure's base region should receive the
TK_PreserveContents trait and avoid invalidation.
Additionally, include a few FIXME tests shown up during testing.
Differential Revision: http://reviews.llvm.org/D19057
llvm-svn: 267413
Diffstat (limited to 'clang/test/Analysis/call-invalidation.cpp')
-rw-r--r-- | clang/test/Analysis/call-invalidation.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index 7297d1ebec2..80323ffcf18 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -118,3 +118,50 @@ void testPureConst() { } +struct PlainStruct { + int x, y; + mutable int z; +}; + +PlainStruct glob; + +void useAnything(void *); +void useAnythingConst(const void *); + +void testInvalidationThroughBaseRegionPointer() { + PlainStruct s1; + s1.x = 1; + s1.z = 1; + clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}} + // Not only passing a structure pointer through const pointer parameter, + // but also passing a field pointer through const pointer parameter + // should preserve the contents of the structure. + useAnythingConst(&(s1.y)); + clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}} + // FIXME: Should say "UNKNOWN", because it is not uncommon to + // modify a mutable member variable through const pointer. + clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}} + useAnything(&(s1.y)); + clang_analyzer_eval(s1.x == 1); // expected-warning{{UNKNOWN}} +} + + +void useFirstConstSecondNonConst(const void *x, void *y); +void useFirstNonConstSecondConst(void *x, const void *y); + +void testMixedConstNonConstCalls() { + PlainStruct s2; + s2.x = 1; + useFirstConstSecondNonConst(&(s2.x), &(s2.y)); + clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}} + s2.x = 1; + useFirstNonConstSecondConst(&(s2.x), &(s2.y)); + clang_analyzer_eval(s2.x == 1); // expected-warning{{UNKNOWN}} + s2.y = 1; + useFirstConstSecondNonConst(&(s2.x), &(s2.y)); + clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}} + s2.y = 1; + useFirstNonConstSecondConst(&(s2.x), &(s2.y)); + clang_analyzer_eval(s2.y == 1); // expected-warning{{UNKNOWN}} +} |