diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2015-12-10 09:28:06 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2015-12-10 09:28:06 +0000 |
commit | 733e71b73b35eccd467c50baf12214d85941f0b0 (patch) | |
tree | d817b5cda01584f26d1cc933c984924fb7a551fe /clang/test/Analysis/symbol-reaper.c | |
parent | a5fbebc2065d12a403f82380cbe0c3a571cfccbe (diff) | |
download | bcm5719-llvm-733e71b73b35eccd467c50baf12214d85941f0b0.tar.gz bcm5719-llvm-733e71b73b35eccd467c50baf12214d85941f0b0.zip |
[analyzer] Fix symbolic element index lifetime.
SymbolReaper was destroying the symbol too early when it was referenced only
from an index SVal of a live ElementRegion.
In order to test certain aspects of this patch, extend the debug.ExprInspection
checker to allow testing SymbolReaper in a direct manner.
Differential Revision: http://reviews.llvm.org/D12726
llvm-svn: 255236
Diffstat (limited to 'clang/test/Analysis/symbol-reaper.c')
-rw-r--r-- | clang/test/Analysis/symbol-reaper.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/clang/test/Analysis/symbol-reaper.c b/clang/test/Analysis/symbol-reaper.c new file mode 100644 index 00000000000..4051c38c2e7 --- /dev/null +++ b/clang/test/Analysis/symbol-reaper.c @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); +void clang_analyzer_warnOnDeadSymbol(int); + +int conjure_index(); + +void test_that_expr_inspection_works() { + do { + int x = conjure_index(); + clang_analyzer_warnOnDeadSymbol(x); + } while(0); // expected-warning{{SYMBOL DEAD}} +} + +// These tests verify the reaping of symbols that are only referenced as +// index values in element regions. Most of the time, depending on where +// the element region, as Loc value, is stored, it is possible to +// recover the index symbol in checker code, which is also demonstrated +// in the return_ptr_range.c test file. + +int arr[3]; + +int *test_element_index_lifetime_in_environment_values() { + int *ptr; + do { + int x = conjure_index(); + clang_analyzer_warnOnDeadSymbol(x); + ptr = arr + x; + } while (0); + return ptr; +} + +void test_element_index_lifetime_in_store_keys() { + do { + int x = conjure_index(); + clang_analyzer_warnOnDeadSymbol(x); + arr[x] = 1; + if (x) {} + } while (0); // no-warning +} + +int *ptr; +void test_element_index_lifetime_in_store_values() { + do { + int x = conjure_index(); + clang_analyzer_warnOnDeadSymbol(x); + ptr = arr + x; + } while (0); // no-warning +} + +struct S1 { + int field; +}; +struct S2 { + struct S1 array[5]; +} s2; + +void test_element_index_lifetime_with_complicated_hierarchy_of_regions() { + do { + int x = conjure_index(); + clang_analyzer_warnOnDeadSymbol(x); + s2.array[x].field = 1; + if (x) {} + } while (0); // no-warning +} + +// Test below checks lifetime of SymbolRegionValue in certain conditions. + +int **ptrptr; +void test_region_lifetime_as_store_value(int *x) { + clang_analyzer_warnOnDeadSymbol((int) x); + *x = 1; + ptrptr = &x; + (void)0; // No-op; make sure the environment forgets things and the GC runs. + clang_analyzer_eval(**ptrptr); // expected-warning{{TRUE}} +} // no-warning |