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