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()8 void 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()23 int *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()33 void 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()43 void 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()58 void 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)70 void 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