diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-02-01 19:49:57 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-02-01 19:49:57 +0000 |
commit | 978aeac1a90020b2a0ae6c7eb7fe65aa8226f74a (patch) | |
tree | 2319e9286563634cb20b20615e5968a3e6a1751e /test/Analysis/array-struct-region.c | |
parent | 0a0f93c90fd397a1aa9f97283c55f8ba0062bf55 (diff) |
[analyzer] Reuse a LazyCompoundVal if its type matches the new region.
This allows us to keep from chaining LazyCompoundVals in cases like this:
CGRect r = CGRectMake(0, 0, 640, 480);
CGRect r2 = r;
CGRect r3 = r2;
Previously we only made this optimization if the struct did not begin with
an aggregate member, to make sure that we weren't picking up an LCV for
the first field of the struct. But since LazyCompoundVals are typed, we can
make that inference directly by comparing types.
This is a pure optimization; the test changes are to guard against possible
future regressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174211 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/array-struct-region.c')
-rw-r--r-- | test/Analysis/array-struct-region.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c index c4d9aff95f..dfb4cf13a9 100644 --- a/test/Analysis/array-struct-region.c +++ b/test/Analysis/array-struct-region.c @@ -267,6 +267,50 @@ static void radar13116945(struct point centerCoordinate) { test13116945(r.center); // no-warning } + +typedef struct { + char data[4]; +} ShortString; + +typedef struct { + ShortString str; + int length; +} ShortStringWrapper; + +void testArrayStructCopy() { + ShortString s = { "abc" }; + ShortString s2 = s; + ShortString s3 = s2; + + clang_analyzer_eval(s3.data[0] == 'a'); // expected-warning{{TRUE}} + clang_analyzer_eval(s3.data[1] == 'b'); // expected-warning{{TRUE}} + clang_analyzer_eval(s3.data[2] == 'c'); // expected-warning{{TRUE}} +} + +void testArrayStructCopyNested() { + ShortString s = { "abc" }; + ShortString s2 = s; + + ShortStringWrapper w = { s2, 0 }; + + clang_analyzer_eval(w.str.data[0] == 'a'); // expected-warning{{TRUE}} + clang_analyzer_eval(w.str.data[1] == 'b'); // expected-warning{{TRUE}} + clang_analyzer_eval(w.str.data[2] == 'c'); // expected-warning{{TRUE}} + clang_analyzer_eval(w.length == 0); // expected-warning{{TRUE}} + + ShortStringWrapper w2 = w; + clang_analyzer_eval(w2.str.data[0] == 'a'); // expected-warning{{TRUE}} + clang_analyzer_eval(w2.str.data[1] == 'b'); // expected-warning{{TRUE}} + clang_analyzer_eval(w2.str.data[2] == 'c'); // expected-warning{{TRUE}} + clang_analyzer_eval(w2.length == 0); // expected-warning{{TRUE}} + + ShortStringWrapper w3 = w2; + clang_analyzer_eval(w3.str.data[0] == 'a'); // expected-warning{{TRUE}} + clang_analyzer_eval(w3.str.data[1] == 'b'); // expected-warning{{TRUE}} + clang_analyzer_eval(w3.str.data[2] == 'c'); // expected-warning{{TRUE}} + clang_analyzer_eval(w3.length == 0); // expected-warning{{TRUE}} +} + // -------------------- // False positives // -------------------- |