(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
call-summaries-2.c
       1  /* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0" } */
       2  /* { dg-require-effective-target alloca } */
       3  
       4  /* There need to be at least two calls to a function for the
       5     call-summarization code to be used.
       6     TODO: add some kind of test that summarization *was* used.  */
       7  
       8  #include <stdlib.h>
       9  #include "analyzer-decls.h"
      10  
      11  extern int external_fn (void *);
      12  
      13  int returns_const (void)
      14  {
      15    return 42;
      16  }
      17  
      18  void test_summarized_returns_const (void)
      19  {
      20    __analyzer_eval (returns_const () == 42); /* { dg-warning "TRUE" } */
      21    __analyzer_eval (returns_const () == 42); /* { dg-warning "TRUE" } */
      22  }
      23  
      24  void test_summarized_returns_const_2 (void)
      25  {
      26    returns_const (); /* { dg-message "when 'returns_const' returns" } */
      27    __analyzer_dump_path (); /* { dg-message "path" } */
      28  }
      29  
      30  int returns_param (int i)
      31  {
      32    return i;
      33  }
      34  
      35  void test_summarized_returns_param (int j)
      36  {
      37    __analyzer_eval (returns_param (j) == j); /* { dg-warning "TRUE" } */
      38    __analyzer_eval (returns_param (j) == j); /* { dg-warning "TRUE" } */
      39  }
      40  
      41  void writes_const_to_ptr (int *p)
      42  {
      43    *p = 42;
      44  }
      45  
      46  void test_summarized_writes_const_to_ptr (void)
      47  {
      48    int i, j;
      49    writes_const_to_ptr (&i);
      50    writes_const_to_ptr (&j);
      51    __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
      52    __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */
      53  }
      54  
      55  // TODO: we should complain about this:
      56  
      57  void test_summarized_write_through_null (void)
      58  {
      59    writes_const_to_ptr (NULL);
      60  }
      61  
      62  void writes_param_to_ptr (int i, int *p)
      63  {
      64    *p = i;
      65  }
      66  
      67  void test_summarized_writes_param_to_ptr (int j)
      68  {
      69    int x, y;
      70    writes_param_to_ptr (j, &x);
      71    writes_param_to_ptr (j, &y);
      72    __analyzer_eval (x == j); /* { dg-warning "TRUE" } */
      73    __analyzer_eval (y == j); /* { dg-warning "TRUE" } */
      74  }
      75  
      76  void test_summarized_writes_param_to_ptr_unknown (int j)
      77  {
      78    int *p = (int *)__analyzer_get_unknown_ptr ();
      79    writes_param_to_ptr (j, p);
      80    __analyzer_eval (*p == j); /* { dg-warning "UNKNOWN" } */
      81  }
      82  
      83  int g;
      84  
      85  void writes_to_global (int i)
      86  {
      87    g = i;
      88  }
      89  
      90  void test_writes_to_global (int x, int y)
      91  {
      92    writes_to_global (x);
      93    __analyzer_eval (g == x); /* { dg-warning "TRUE" } */
      94  
      95    writes_to_global (y);
      96    __analyzer_eval (g == y); /* { dg-warning "TRUE" } */
      97  }
      98  
      99  int reads_from_global (void)
     100  {
     101    return g;
     102  }
     103  
     104  void test_reads_from_global (int x, int y)
     105  {
     106    g = x;
     107    __analyzer_eval (reads_from_global () == x); /* { dg-warning "TRUE" } */
     108  
     109    g = y;
     110    __analyzer_eval (reads_from_global () == y); /* { dg-warning "TRUE" } */
     111  }
     112  
     113  /* Example of a unary op.  */
     114  
     115  int returns_negation (int i)
     116  {
     117    return -i;
     118  }
     119  
     120  void test_returns_negation (int x)
     121  {
     122    __analyzer_eval (returns_negation (5) == -5); /* { dg-warning "TRUE" } */
     123    __analyzer_eval (returns_negation (x) == -x); /* { dg-warning "TRUE" } */
     124    __analyzer_eval (returns_negation (-x) == x); /* { dg-warning "TRUE" } */
     125  }
     126  
     127  /* Example of a binary op.  */
     128  
     129  int returns_sum (int i, int j)
     130  {
     131    return i + j;
     132  }
     133  
     134  void test_returns_sum (int x, int y)
     135  {
     136    __analyzer_eval (returns_sum (5, 3) == 8); /* { dg-warning "TRUE" } */
     137    __analyzer_eval (returns_sum (7, 2) == 9); /* { dg-warning "TRUE" } */
     138    __analyzer_eval (returns_sum (x, y) == x + y); /* { dg-warning "TRUE" } */
     139  }
     140  
     141  struct coord
     142  {
     143    int x;
     144    int y;
     145  };
     146  
     147  struct coord make_coord (int x, int y)
     148  {
     149    struct coord result = {x, y};
     150    return result;
     151  }
     152  
     153  void test_make_coord (int i, int j)
     154  {
     155    struct coord c1 = make_coord (3, 4);
     156    __analyzer_eval (c1.x == 3); /* { dg-warning "TRUE" } */
     157    __analyzer_eval (c1.y == 4); /* { dg-warning "TRUE" } */
     158  
     159    struct coord c2 = make_coord (i, j);
     160    __analyzer_eval (c2.x == i); /* { dg-warning "TRUE" } */
     161    __analyzer_eval (c2.y == j); /* { dg-warning "TRUE" } */
     162  }
     163  
     164  /* Example of nested usage of summaries.  */
     165  
     166  struct rect
     167  {
     168    struct coord nw;
     169    struct coord se;
     170  };
     171  
     172  struct rect make_rect (int top, int bottom, int left, int right)
     173  {
     174    struct rect result = {make_coord (left, top),
     175  			make_coord (right, bottom)};
     176    return result;
     177  }
     178  
     179  void test_make_rect (int top, int bottom, int left, int right)
     180  {
     181    struct rect r1 = make_rect (3, 4, 5, 6);
     182    __analyzer_eval (r1.nw.y == 3); /* { dg-warning "TRUE" } */
     183    __analyzer_eval (r1.se.y == 4); /* { dg-warning "TRUE" } */
     184    __analyzer_eval (r1.nw.x == 5); /* { dg-warning "TRUE" } */
     185    __analyzer_eval (r1.se.x == 6); /* { dg-warning "TRUE" } */
     186  
     187    struct rect r2 = make_rect (top, bottom, left, right);
     188    __analyzer_eval (r2.nw.y == top); /* { dg-warning "TRUE" } */
     189    __analyzer_eval (r2.se.y == bottom); /* { dg-warning "TRUE" } */
     190    __analyzer_eval (r2.nw.x == left); /* { dg-warning "TRUE" } */
     191    __analyzer_eval (r2.se.x == right); /* { dg-warning "TRUE" } */
     192  }
     193  
     194  const char *returns_str (void)
     195  {
     196    return "abc";
     197  }
     198  
     199  void test_returns_str (void)
     200  {
     201    __analyzer_eval (returns_str () != NULL); /* { dg-warning "TRUE" } */
     202    __analyzer_eval (returns_str ()[0] == 'a'); /* { dg-warning "TRUE" } */
     203    __analyzer_eval (returns_str ()[1] == 'b'); /* { dg-warning "TRUE" } */
     204    __analyzer_eval (returns_str ()[2] == 'c'); /* { dg-warning "TRUE" } */
     205    __analyzer_eval (returns_str ()[3] == '\0'); /* { dg-warning "TRUE" } */
     206  }
     207  
     208  int returns_field (struct coord *p)
     209  {
     210    return p->y;
     211  }
     212  
     213  void test_returns_field (struct coord *q)
     214  {
     215    __analyzer_eval (returns_field (q) == q->y); /* { dg-warning "TRUE" } */
     216    __analyzer_eval (returns_field (q) == q->y); /* { dg-warning "TRUE" } */
     217  }
     218  
     219  void writes_to_fields (struct coord *p, int x, int y)
     220  {
     221    p->x = x;
     222    p->y = y;
     223  }
     224  
     225  void test_writes_to_field (struct coord *q, int qx, int qy)
     226  {
     227    struct coord a, b;
     228    writes_to_fields (&a, 1, 2);
     229    __analyzer_eval (a.x == 1); /* { dg-warning "TRUE" } */
     230    __analyzer_eval (a.y == 2); /* { dg-warning "TRUE" } */
     231    writes_to_fields (&b, 3, 4);
     232    __analyzer_eval (b.x == 3); /* { dg-warning "TRUE" } */
     233    __analyzer_eval (b.y == 4); /* { dg-warning "TRUE" } */
     234    writes_to_fields (q, qx, qy);
     235    __analyzer_eval (q->x == qx); /* { dg-warning "TRUE" } */
     236    __analyzer_eval (q->y == qy); /* { dg-warning "TRUE" } */
     237  }
     238  
     239  /* Example of nested function summarization.  */
     240  
     241  int get_min_x (struct rect *p)
     242  {
     243    return p->nw.x;
     244  }
     245  
     246  int get_min_y (struct rect *p)
     247  {
     248    return p->nw.y;
     249  }
     250  
     251  int get_max_x (struct rect *p)
     252  {
     253    return p->se.x;
     254  }
     255  
     256  int get_max_y (struct rect *p)
     257  {
     258    return p->se.y;
     259  }
     260  
     261  int get_area (struct rect *p)
     262  {
     263    return ((get_max_x (p) - get_min_x (p))
     264  	  * (get_max_y (p) - get_min_y (p)));
     265  }
     266  
     267  void test_get_area (int top, int bottom, int left, int right, struct rect *p)
     268  {
     269    {
     270      /* 1x1 at origin.  */
     271      struct rect a = make_rect (0, 1, 0, 1);
     272      __analyzer_eval (get_min_y (&a) == 0); /* { dg-warning "TRUE" } */
     273      __analyzer_eval (get_max_y (&a) == 1); /* { dg-warning "TRUE" } */
     274      __analyzer_eval (get_min_x (&a) == 0); /* { dg-warning "TRUE" } */
     275      __analyzer_eval (get_max_x (&a) == 1); /* { dg-warning "TRUE" } */
     276      __analyzer_eval (get_area (&a) == 1); /* { dg-warning "TRUE" } */
     277    }
     278  
     279    {
     280      /* 4x5. */
     281      struct rect b = make_rect (3, 7, 4, 9);
     282      __analyzer_eval (get_min_y (&b) == 3); /* { dg-warning "TRUE" } */
     283      __analyzer_eval (get_max_y (&b) == 7); /* { dg-warning "TRUE" } */
     284      __analyzer_eval (get_min_x (&b) == 4); /* { dg-warning "TRUE" } */
     285      __analyzer_eval (get_max_x (&b) == 9); /* { dg-warning "TRUE" } */
     286      __analyzer_eval (get_area (&b) == 20); /* { dg-warning "TRUE" } */
     287    }
     288  
     289    {
     290      /* Symbolic.  */
     291      struct rect c = make_rect (top, bottom, left, right);
     292      __analyzer_eval (get_min_y (&c) == top); /* { dg-warning "TRUE" } */
     293      __analyzer_eval (get_max_y (&c) == bottom); /* { dg-warning "TRUE" } */
     294      __analyzer_eval (get_min_x (&c) == left); /* { dg-warning "TRUE" } */
     295      __analyzer_eval (get_max_x (&c) == right); /* { dg-warning "TRUE" } */
     296      __analyzer_eval (get_area (&c) == ((right - left) * (bottom - top))); /* { dg-warning "TRUE" } */
     297    }
     298  
     299    /* Symbolic via ptr.  */
     300    __analyzer_eval (get_min_y (p) == p->nw.y); /* { dg-warning "TRUE" } */
     301    __analyzer_eval (get_max_y (p) == p->se.y); /* { dg-warning "TRUE" } */
     302    __analyzer_eval (get_min_x (p) == p->nw.x); /* { dg-warning "TRUE" } */
     303    __analyzer_eval (get_max_x (p) == p->se.x); /* { dg-warning "TRUE" } */
     304    __analyzer_eval (get_area (p) == ((p->se.x - p->nw.x) * (p->se.y - p->nw.y))); /* { dg-warning "TRUE" } */
     305  }
     306  
     307  int returns_element (int i)
     308  {
     309    static const int arr[3] = {7, 8, 9};
     310    return arr[i];
     311  }
     312  
     313  void test_returns_element (int j)
     314  {
     315    __analyzer_eval (returns_element (0) == 7); /* { dg-warning "UNKNOWN" } */
     316    __analyzer_eval (returns_element (1) == 8); /* { dg-warning "UNKNOWN" } */
     317    __analyzer_eval (returns_element (2) == 9); /* { dg-warning "UNKNOWN" } */
     318    __analyzer_eval (returns_element (3) == 10); /* { dg-warning "UNKNOWN" } */
     319    // TODO: out of bounds
     320  }
     321  
     322  const int *returns_element_ptr (int i)
     323  {
     324    static const int arr[3] = {7, 8, 9};
     325    return &arr[i];
     326  }
     327  
     328  int test_returns_element_ptr (int j)
     329  {
     330    __analyzer_eval (*returns_element_ptr (0) == 7); /* { dg-warning "TRUE" } */
     331    __analyzer_eval (*returns_element_ptr (1) == 8); /* { dg-warning "TRUE" } */
     332    __analyzer_eval (*returns_element_ptr (2) == 9); /* { dg-warning "TRUE" } */
     333    return *returns_element_ptr (3); /* { dg-warning "buffer over-read" } */
     334    /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } .-1 } */
     335  }
     336  
     337  int returns_offset (int arr[3], int i)
     338  {
     339    return arr[i];
     340  }
     341  
     342  void test_returns_offset (int outer_arr[3], int idx)
     343  {
     344    int a[3] = {4, 5, 6};
     345    __analyzer_eval (returns_offset (a, 0) == 4); /* { dg-warning "TRUE" } */
     346    __analyzer_eval (returns_offset (a, 1) == 5); /* { dg-warning "TRUE" } */
     347    __analyzer_eval (returns_offset (a, 2) == 6); /* { dg-warning "TRUE" } */
     348    __analyzer_eval (returns_offset (a, idx) == a[idx]); /* { dg-warning "UNKNOWN" } */
     349    __analyzer_eval (returns_offset (outer_arr, 0) == outer_arr[0]); /* { dg-warning "TRUE" } */
     350    __analyzer_eval (returns_offset (outer_arr, idx) == outer_arr[idx]); /* { dg-warning "TRUE" } */  
     351  }
     352  
     353  int returns_offset_2 (int arr[], int i)
     354  {
     355    return arr[i];
     356  }
     357  
     358  void test_returns_offset_2 (int outer_arr[], int idx)
     359  {
     360    int a[3] = {4, 5, 6};
     361    __analyzer_eval (returns_offset_2 (a, 0) == 4); /* { dg-warning "TRUE" } */
     362    __analyzer_eval (returns_offset_2 (a, 1) == 5); /* { dg-warning "TRUE" } */
     363    __analyzer_eval (returns_offset_2 (a, 2) == 6); /* { dg-warning "TRUE" } */
     364    __analyzer_eval (returns_offset_2 (a, idx) == a[idx]); /* { dg-warning "UNKNOWN" } */
     365    __analyzer_eval (returns_offset_2 (outer_arr, 0) == outer_arr[0]); /* { dg-warning "TRUE" } */
     366    __analyzer_eval (returns_offset_2 (outer_arr, idx) == outer_arr[idx]); /* { dg-warning "TRUE" } */  
     367  }
     368  
     369  int returns_offset_3 (int *p, int i)
     370  {
     371    return p[i];
     372  }
     373  
     374  void test_returns_offset_3 (int *q, int j)
     375  {
     376    __analyzer_eval (returns_offset_3 (q, j) == q[j]); /* { dg-warning "TRUE" } */
     377    __analyzer_eval (returns_offset_3 (q, j) == q[j]); /* { dg-warning "TRUE" } */
     378  }
     379  
     380  /* With state merging, this is summarized as returning "UNKNOWN".  */
     381  
     382  int two_outcomes (int flag, int x, int y)
     383  {
     384    if (flag)
     385      return x;
     386    else
     387      return y;
     388  }
     389  
     390  void test_two_outcomes (int outer_flag, int a, int b)
     391  {
     392    int r;
     393    __analyzer_eval (two_outcomes (1, a, b) == a); /* { dg-warning "UNKNOWN" } */
     394    __analyzer_eval (two_outcomes (0, a, b) == b); /* { dg-warning "UNKNOWN" } */
     395    r = two_outcomes (outer_flag, a, b);
     396    if (outer_flag)
     397      __analyzer_eval (r == a); /* { dg-warning "UNKNOWN" } */
     398    else
     399      __analyzer_eval (r == b); /* { dg-warning "UNKNOWN" } */  
     400  }
     401  
     402  /* Verify that summary replays capture postconditions.  */
     403  
     404  void check_int_nonnegative (int i)
     405  {
     406    if (i < 0)
     407      __builtin_unreachable ();
     408  }
     409  
     410  void test_check_int_nonnegative (int i, int j)
     411  {
     412    __analyzer_eval (i >= 0); /* { dg-warning "UNKNOWN" } */
     413    check_int_nonnegative (i);
     414    __analyzer_eval (i >= 0); /* { dg-warning "TRUE" } */
     415  
     416    __analyzer_eval (j >= 0); /* { dg-warning "UNKNOWN" } */
     417    check_int_nonnegative (j);
     418    __analyzer_eval (j >= 0); /* { dg-warning "TRUE" } */
     419  }
     420  
     421  void calls_external_fn (void)
     422  {
     423    external_fn (NULL);
     424  }
     425  
     426  void test_calls_external_fn (void)
     427  {
     428    g = 1;
     429    __analyzer_eval (g == 1); /* { dg-warning "TRUE" } */
     430    calls_external_fn ();
     431    calls_external_fn ();
     432    __analyzer_eval (g == 1); /* { dg-warning "UNKNOWN" "expected" { xfail *-*-* } } */
     433    /* { dg-bogus "TRUE" "bogus" { xfail *-*-* } .-1 } */
     434    // TODO(xfails)
     435  }
     436  
     437  int returns_iterator (int n)
     438  {
     439    int i;
     440    for (i = 0; i < n; i++)
     441      {
     442      }
     443    return i;
     444  }
     445  
     446  void test_returns_iterator (int j, int k)
     447  {
     448    __analyzer_eval (returns_iterator (j) == j); /* { dg-warning "UNKNOWN" } */
     449    __analyzer_eval (returns_iterator (k) == k); /* { dg-warning "UNKNOWN" } */
     450    /* TODO: ideally we'd capture these equalities, but this is an issue 
     451       with how we handle loops.  */
     452  }
     453  
     454  int returns_external_result (void)
     455  {
     456    return external_fn (NULL);
     457  }
     458  
     459  int test_returns_external_result (void)
     460  {
     461    int i, j;
     462    i = returns_external_result ();
     463    j = returns_external_result ();
     464    __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */
     465    return i * j;
     466  }
     467  
     468  int uses_alloca (int i)
     469  {
     470    int *p = __builtin_alloca (sizeof (int));
     471    *p = i;
     472    return *p;
     473  }
     474  
     475  void test_uses_alloca (int x)
     476  {
     477    __analyzer_eval (uses_alloca (42) == 42); /* { dg-warning "TRUE" } */
     478    __analyzer_eval (uses_alloca (x) == x); /* { dg-warning "TRUE" } */
     479  }
     480  
     481  struct bits
     482  {
     483    unsigned b0 : 1;
     484    unsigned b1 : 1;
     485    unsigned b2 : 1;
     486    unsigned b3 : 1;
     487    unsigned b4 : 1;
     488    unsigned b5 : 1;
     489    unsigned b6 : 1;
     490    unsigned b7 : 1;
     491  };
     492  
     493  int returns_bitfield (struct bits b)
     494  {
     495    return b.b3;
     496  }
     497  
     498  void test_returns_bitfield (struct bits s)
     499  {
     500    __analyzer_eval (returns_bitfield (s) == s.b3); /* { dg-warning "UNKNOWN" } */
     501    __analyzer_eval (returns_bitfield (s) == s.b3); /* { dg-warning "UNKNOWN" } */
     502    // TODO: ideally it would figure out that these are equal
     503  }
     504  
     505  int consume_two_ints_from_va_list (__builtin_va_list ap)
     506  {
     507    int i, j;
     508    i = __builtin_va_arg (ap, int);
     509    j = __builtin_va_arg (ap, int);
     510    return i * j;
     511  }
     512  
     513  int test_consume_two_ints_from_va_list (__builtin_va_list ap1)
     514  {
     515    int p1, p2;
     516    __builtin_va_list ap2;
     517    __builtin_va_copy (ap2, ap1);
     518    p1 = consume_two_ints_from_va_list (ap1);
     519    p2 = consume_two_ints_from_va_list (ap2);
     520    __analyzer_eval (p1 == p2); /* { dg-warning "UNKNOWN" } */
     521    // TODO: ideally it would figure out these are equal
     522    __builtin_va_end (ap2);
     523  }
     524  
     525  int consume_two_ints_from_varargs (int placeholder, ...)
     526  {
     527    int i, j;
     528    __builtin_va_list ap;
     529    __builtin_va_start (ap, placeholder);
     530    i = __builtin_va_arg (ap, int);
     531    j = __builtin_va_arg (ap, int);
     532    __builtin_va_end (ap);
     533    return i * j;
     534  }
     535  
     536  void test_consume_two_ints_from_varargs (int x, int y)
     537  {
     538    __analyzer_eval (consume_two_ints_from_varargs (0, 4, 5) == 20); /* { dg-warning "UNKNOWN" } */
     539    __analyzer_eval (consume_two_ints_from_varargs (0, 3, 6) == 18); /* { dg-warning "UNKNOWN" } */
     540    __analyzer_eval (consume_two_ints_from_varargs (0, x, 6) == x * y); /* { dg-warning "UNKNOWN" } */
     541    // TODO: ideally it would figure these out
     542  }
     543  
     544  extern int const_fn_1 (int) __attribute__ ((const));
     545  int calls_const_fn (int i)
     546  {
     547    return const_fn_1 (i);
     548  }
     549  
     550  void test_calls_const_fn (int x)
     551  {
     552    int r1, r2;
     553    r1 = calls_const_fn (x);
     554    r2 = calls_const_fn (x);
     555    __analyzer_eval (r1 == r2); /* { dg-warning "TRUE" } */
     556  }
     557  
     558  typedef struct iv2 { int arr[2]; } iv2_t;
     559  typedef struct iv4 { int arr[4]; } iv4_t;
     560  
     561  iv2_t returns_iv2_t (int x, int y)
     562  {
     563    iv2_t result = {x, y};
     564    return result;
     565  }
     566  
     567  void test_returns_iv2_t (int a, int b)
     568  {
     569    __analyzer_eval (returns_iv2_t (a, b).arr[0] == a); /* { dg-warning "TRUE" } */
     570    __analyzer_eval (returns_iv2_t (a, b).arr[1] == b); /* { dg-warning "TRUE" } */
     571  }
     572  
     573  iv4_t returns_iv4_t (int a, iv2_t bc, int d)
     574  {
     575    iv4_t result = {a, bc.arr[0], bc.arr[1], d};
     576    return result;
     577  }
     578  
     579  void test_returns_iv4_t (int p, iv2_t qr, int s)
     580  {
     581    __analyzer_eval (returns_iv4_t (p, qr, s).arr[0] == p); /* { dg-warning "TRUE" } */
     582    __analyzer_eval (returns_iv4_t (p, qr, s).arr[1] == qr.arr[0]); /* { dg-warning "UNKNOWN" } */
     583    __analyzer_eval (returns_iv4_t (p, qr, s).arr[2] == qr.arr[1]); /* { dg-warning "UNKNOWN" } */
     584    __analyzer_eval (returns_iv4_t (p, qr, s).arr[3] == s); /* { dg-warning "TRUE" } */
     585    // TODO: ideally the UNKNOWNs would be TRUEs.
     586  }
     587  
     588  void copies_iv2_t (int *p, iv2_t xy)
     589  {
     590    __builtin_memcpy (p, &xy, sizeof (xy));
     591  }
     592  
     593  void test_copies_iv2_t (iv2_t ab, iv2_t cd)
     594  {
     595    iv4_t t;
     596    copies_iv2_t (&t.arr[0], ab);
     597    copies_iv2_t (&t.arr[2], cd);
     598    __analyzer_eval (t.arr[0] = ab.arr[0]); /* { dg-warning "UNKNOWN" } */
     599    __analyzer_eval (t.arr[1] = ab.arr[1]); /* { dg-warning "UNKNOWN" } */
     600    __analyzer_eval (t.arr[2] = cd.arr[0]); /* { dg-warning "UNKNOWN" } */
     601    __analyzer_eval (t.arr[3] = cd.arr[1]); /* { dg-warning "UNKNOWN" } */
     602    // TODO: ideally the UNKNOWNs would be TRUEs.
     603  }
     604  
     605  void partially_inits (int *p, int v)
     606  {
     607    p[1] = v;
     608  }
     609  
     610  void test_partially_inits_0 (int x)
     611  {
     612    int arr[2];
     613    partially_inits (arr, x);
     614    partially_inits (arr, x);
     615  
     616    __analyzer_eval (arr[0]); /* { dg-warning "use of uninitialized value 'arr\\\[0\\\]'" } */
     617  }
     618  
     619  void test_partially_inits_1 (int x)
     620  {
     621    int arr[2];
     622    partially_inits (arr, x);
     623    partially_inits (arr, x);
     624  
     625    __analyzer_eval (arr[1] == x); /* { dg-bogus "use of uninitialized value 'arr\\\[1\\\]'" "uninit" { xfail *-*-* } } */
     626    // TODO(xfail), and eval should be "TRUE"
     627  }
     628  
     629  int uses_switch (int i)
     630  {
     631    switch (i)
     632      {
     633      case 0:
     634        return 42;
     635      case 1:
     636        return 17;
     637      default:
     638        return i * 2;
     639      }
     640  }
     641  
     642  void test_uses_switch (int x)
     643  {
     644    __analyzer_eval (uses_switch (0) == 42); /* { dg-warning "UNKNOWN" } */
     645    __analyzer_eval (uses_switch (1) == 17); /* { dg-warning "UNKNOWN" } */
     646    __analyzer_eval (uses_switch (2) == x * 2); /* { dg-warning "UNKNOWN" } */
     647    // TODO: ideally the UNKNOWNs would be TRUEs.
     648  }
     649  
     650  int *returns_ptr_to_first_field (struct coord *p)
     651  {
     652    return &p->x;
     653  }
     654  
     655  void test_returns_ptr_to_first_field (struct coord *q)
     656  {
     657    __analyzer_eval (returns_ptr_to_first_field (q) == (int *)q); /* { dg-warning "UNKNOWN" } */
     658    __analyzer_eval (returns_ptr_to_first_field (q) == (int *)q); /* { dg-warning "UNKNOWN" } */
     659    // TODO: ideally the UNKNOWNs would be TRUEs.
     660  }