1  /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
       2  
       3  #include "../analyzer-decls.h"
       4  
       5  typedef struct boxed_int { int value; } boxed_int;
       6  
       7  extern boxed_int boxed_int_add (boxed_int a, boxed_int b);
       8  extern boxed_int boxed_int_mul (boxed_int a, boxed_int b);
       9  
      10  boxed_int  __attribute__((noinline))
      11  noinline_boxed_int_add (boxed_int a, boxed_int b)
      12  {
      13    boxed_int result;
      14    result.value = a.value + b.value;
      15    return result;
      16  }
      17  
      18  static inline boxed_int
      19  inline_boxed_int_add (boxed_int a, boxed_int b)
      20  {
      21    boxed_int result;
      22    result.value = a.value + b.value;
      23    return result;
      24  }
      25  
      26  boxed_int
      27  test_1 (boxed_int a, boxed_int b)
      28  {
      29    boxed_int result = boxed_int_add (boxed_int_mul (a, a),
      30  				    boxed_int_mul (b, b));
      31    return result;
      32  }
      33  
      34  void
      35  test_2a (void)
      36  {
      37    boxed_int arr[4];
      38    arr[0].value = 1;
      39    arr[1].value = 2;
      40    arr[2].value = 3;
      41    arr[3].value = 4;
      42    boxed_int sum;
      43    sum.value = arr[0].value + arr[1].value + arr[2].value + arr[3].value;
      44    __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */
      45  }
      46  
      47  void
      48  test_2b (void)
      49  {
      50    boxed_int a, b, c, d;
      51    a.value = 1;
      52    b.value = 2;
      53    c.value = 3;
      54    d.value = 4;
      55    boxed_int sum;
      56    sum.value = a.value + b.value + c.value + d.value;
      57    __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */
      58  }
      59  
      60  void
      61  test_2c (void)
      62  {
      63    boxed_int a, b, c, d;
      64    a.value = 1;
      65    b.value = 2;
      66    c.value = 3;
      67    d.value = 4;
      68    boxed_int sum = inline_boxed_int_add (inline_boxed_int_add (a, b),
      69  					inline_boxed_int_add (c, d));
      70    __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */
      71  }
      72  
      73  void
      74  test_2d (void)
      75  {
      76    boxed_int a, b, c, d;
      77    a.value = 1;
      78    b.value = 2;
      79    c.value = 3;
      80    d.value = 4;
      81    boxed_int sum = noinline_boxed_int_add (noinline_boxed_int_add (a, b),
      82  					  noinline_boxed_int_add (c, d));
      83    __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */
      84  }
      85  
      86  /* Pointer to a local.  */
      87  
      88  void test_4 (void)
      89  {
      90    boxed_int i;
      91    int *p = &i.value;
      92    i.value = 1;
      93    *p = 2;
      94    __analyzer_eval (i.value == 2); /* { dg-warning "TRUE" } */
      95  }
      96  
      97  /* Local array.  */
      98  
      99  void test_5 (void)
     100  {
     101    boxed_int a[10];
     102    a[3].value = 5; /* ARRAY_REF.  */
     103    __analyzer_eval (a[3].value == 5); /* { dg-warning "TRUE" } */
     104  }
     105  
     106  /* Local array, but using an unknown index.  */
     107  
     108  void test_5a (int idx)
     109  {
     110    boxed_int a[10];
     111    a[idx].value = 5; /* ARRAY_REF.  */
     112    __analyzer_eval (a[idx].value == 5); /* { dg-warning "TRUE" } */
     113  }
     114  
     115  /* Array passed in as a param.  */
     116  
     117  void test_6 (boxed_int a[10])
     118  {
     119    /* POINTER_PLUS_EXPR then a MEM_REF.  */
     120    __analyzer_eval (a[3].value == 42); /* { dg-warning "UNKNOWN" } */
     121    a[3].value = 42;
     122    __analyzer_eval (a[3].value == 42); /* { dg-warning "TRUE" } */
     123  }
     124  
     125  /* Array passed in as a param ptr.  */
     126  
     127  void test_7 (boxed_int *a)
     128  {
     129    __analyzer_eval (a[3].value == 42); /* { dg-warning "UNKNOWN" } */
     130    a[3].value = 42;
     131    __analyzer_eval (a[3].value == 42); /* { dg-warning "TRUE" } */
     132  }
     133  
     134  /* Globals.  */
     135  
     136  boxed_int glob_a;
     137  
     138  void test_10 (void)
     139  {
     140    __analyzer_eval (glob_a.value == 42); /* { dg-warning "UNKNOWN" } */
     141    glob_a.value = 42;
     142    __analyzer_eval (glob_a.value == 42); /* { dg-warning "TRUE" } */
     143  }
     144  
     145  /* Use of uninit value.  */
     146  int test_12a (void)
     147  {
     148    boxed_int i; /* { dg-message "region created on stack here" } */
     149    return i.value; /* { dg-warning "use of uninitialized value 'i.value'" } */
     150  }
     151  
     152  /* Use of uninit value.  */
     153  boxed_int test_12b (void)
     154  {
     155    boxed_int i; /* { dg-message "region created on stack here" } */
     156    return i; /* { dg-warning "use of uninitialized value '\[^\n\r\]*'" } */
     157  }
     158  
     159  void test_loop (void)
     160  {
     161    boxed_int i;
     162  
     163    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
     164  
     165    for (i.value=0; i.value<256; i.value++) {
     166        __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
     167    }
     168  
     169    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
     170  }