1 // RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s 2 3 void clang_analyzer_eval(int); 4 void clang_analyzer_warnOnDeadSymbol(int); 5 6 int conjure_index(); 7 test_that_expr_inspection_works()8void test_that_expr_inspection_works() { 9 do { 10 int x = conjure_index(); 11 clang_analyzer_warnOnDeadSymbol(x); 12 } while(0); // expected-warning{{SYMBOL DEAD}} 13 } 14 15 // These tests verify the reaping of symbols that are only referenced as 16 // index values in element regions. Most of the time, depending on where 17 // the element region, as Loc value, is stored, it is possible to 18 // recover the index symbol in checker code, which is also demonstrated 19 // in the return_ptr_range.c test file. 20 21 int arr[3]; 22 test_element_index_lifetime_in_environment_values()23int *test_element_index_lifetime_in_environment_values() { 24 int *ptr; 25 do { 26 int x = conjure_index(); 27 clang_analyzer_warnOnDeadSymbol(x); 28 ptr = arr + x; 29 } while (0); 30 return ptr; 31 } 32 test_element_index_lifetime_in_store_keys()33void test_element_index_lifetime_in_store_keys() { 34 do { 35 int x = conjure_index(); 36 clang_analyzer_warnOnDeadSymbol(x); 37 arr[x] = 1; 38 if (x) {} 39 } while (0); // no-warning 40 } 41 42 int *ptr; test_element_index_lifetime_in_store_values()43void test_element_index_lifetime_in_store_values() { 44 do { 45 int x = conjure_index(); 46 clang_analyzer_warnOnDeadSymbol(x); 47 ptr = arr + x; 48 } while (0); // no-warning 49 } 50 51 struct S1 { 52 int field; 53 }; 54 struct S2 { 55 struct S1 array[5]; 56 } s2; 57 test_element_index_lifetime_with_complicated_hierarchy_of_regions()58void test_element_index_lifetime_with_complicated_hierarchy_of_regions() { 59 do { 60 int x = conjure_index(); 61 clang_analyzer_warnOnDeadSymbol(x); 62 s2.array[x].field = 1; 63 if (x) {} 64 } while (0); // no-warning 65 } 66 67 // Test below checks lifetime of SymbolRegionValue in certain conditions. 68 69 int **ptrptr; test_region_lifetime_as_store_value(int * x)70void test_region_lifetime_as_store_value(int *x) { 71 clang_analyzer_warnOnDeadSymbol((int) x); 72 *x = 1; 73 ptrptr = &x; 74 (void)0; // No-op; make sure the environment forgets things and the GC runs. 75 clang_analyzer_eval(**ptrptr); // expected-warning{{TRUE}} 76 } // no-warning 77