brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · e8ea1b5 Raw
161 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -Wno-pointer-to-int-cast -verify %s2 3void clang_analyzer_eval(int);4void clang_analyzer_warnOnDeadSymbol(int);5void clang_analyzer_numTimesReached(void);6void clang_analyzer_warnIfReached(void);7 8void exit(int);9 10int conjure_index(void);11 12void test_that_expr_inspection_works(void) {13  do {14    int x = conjure_index();15    clang_analyzer_warnOnDeadSymbol(x);16  } while(0); // expected-warning{{SYMBOL DEAD}}17 18  // Make sure we don't accidentally split state in ExprInspection.19  clang_analyzer_numTimesReached(); // expected-warning{{1}}20}21 22// These tests verify the reaping of symbols that are only referenced as23// index values in element regions. Most of the time, depending on where24// the element region, as Loc value, is stored, it is possible to25// recover the index symbol in checker code, which is also demonstrated26// in the return_ptr_range.c test file.27 28int arr[3];29 30int *test_element_index_lifetime_in_environment_values(void) {31  int *ptr;32  do {33    int x = conjure_index();34    clang_analyzer_warnOnDeadSymbol(x);35    ptr = arr + x;36  } while (0);37  return ptr;38}39 40void test_element_index_lifetime_in_store_keys(void) {41  do {42    int x = conjure_index();43    clang_analyzer_warnOnDeadSymbol(x);44    arr[x] = 1;45    if (x) {}46  } while (0); // no-warning47}48 49int *ptr;50void test_element_index_lifetime_in_store_values(void) {51  do {52    int x = conjure_index();53    clang_analyzer_warnOnDeadSymbol(x);54    ptr = arr + x;55  } while (0); // no-warning56}57 58struct S1 {59  int field;60};61struct S2 {62  struct S1 array[5];63} s2;64struct S3 {65  void *field;66};67 68struct S1 *conjure_S1(void);69struct S3 *conjure_S3(void);70 71void test_element_index_lifetime_with_complicated_hierarchy_of_regions(void) {72  do {73    int x = conjure_index();74    clang_analyzer_warnOnDeadSymbol(x);75    s2.array[x].field = 1;76    if (x) {}77  } while (0); // no-warning78}79 80void test_loc_as_integer_element_index_lifetime(void) {81  do {82    int x;83    struct S3 *s = conjure_S3();84    clang_analyzer_warnOnDeadSymbol((int)s);85    x = (int)&(s->field);86    ptr = &arr[x];87    if (s) {}88  } while (0);89}90 91// Test below checks lifetime of SymbolRegionValue in certain conditions.92 93int **ptrptr;94void test_region_lifetime_as_store_value(int *x) {95  clang_analyzer_warnOnDeadSymbol((int) x);96  *x = 1;97  ptrptr = &x;98  (void)0; // No-op; make sure the environment forgets things and the GC runs.99  clang_analyzer_eval(**ptrptr); // expected-warning{{TRUE}}100} // no-warning101 102int *produce_region_referenced_only_through_field_in_environment_value(void) {103  struct S1 *s = conjure_S1();104  clang_analyzer_warnOnDeadSymbol((int) s);105  int *x = &s->field;106  return x;107}108 109void test_region_referenced_only_through_field_in_environment_value(void) {110  produce_region_referenced_only_through_field_in_environment_value();111} // expected-warning{{SYMBOL DEAD}}112 113void test_region_referenced_only_through_field_in_store_value(void) {114  struct S1 *s = conjure_S1();115  clang_analyzer_warnOnDeadSymbol((int) s);116  ptr = &s->field; // Write the symbol into a global. It should live forever.117  if (!s) {118    exit(0); // no-warning (symbol should not die here)119    // exit() is noreturn.120    clang_analyzer_warnIfReached(); // no-warning121  }122  if (!ptr) { // no-warning (symbol should not die here)123    // We exit()ed under these constraints earlier.124    clang_analyzer_warnIfReached(); // no-warning125  }126  // The exit() call invalidates globals. The symbol will die here because127  // the exit() statement itself is already over and there's no better statement128  // to put the diagnostic on.129} // expected-warning{{SYMBOL DEAD}}130 131void test_zombie_referenced_only_through_field_in_store_value(void) {132  struct S1 *s = conjure_S1();133  clang_analyzer_warnOnDeadSymbol((int) s);134  int *x = &s->field;135} // expected-warning{{SYMBOL DEAD}}136 137void double_dereference_of_implicit_value_aux1(int *p) {138  *p = 0;139}140 141void double_dereference_of_implicit_value_aux2(int *p) {142  if (*p != 0)143    clang_analyzer_warnIfReached(); // no-warning144}145 146void test_double_dereference_of_implicit_value(int **x) {147  clang_analyzer_warnOnDeadSymbol(**x);148  int **y = x;149  {150    double_dereference_of_implicit_value_aux1(*y);151    // Give time for symbol reaping to happen.152    ((void)0);153    // The symbol for **y was cleaned up from the Store at this point,154    // even though it was not perceived as dead when asked explicitly.155    // For that reason the SYMBOL DEAD warning never appeared at this point.156    double_dereference_of_implicit_value_aux2(*y);157  }158  // The symbol is generally reaped here regardless.159  ((void)0); // expected-warning{{SYMBOL DEAD}}160}161