(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
data-model-1.c
       1  /* { dg-require-effective-target alloca } */
       2  /* { dg-additional-options "-fno-ipa-modref" } */
       3  
       4  #include <stdlib.h>
       5  #include <string.h>
       6  #include <stdio.h>
       7  #include "analyzer-decls.h"
       8  
       9  struct foo
      10  {
      11    int i;
      12  };
      13  
      14  /* Fields of a local.  */
      15  
      16  void test_1 (void)
      17  {
      18    struct foo f;
      19    f.i = 1;
      20    __analyzer_eval (f.i == 1); /* { dg-warning "TRUE" } */
      21  }
      22  
      23  /* Fields of a param.  */
      24  
      25  void test_2 (struct foo f)
      26  {
      27    __analyzer_eval (f.i == 2); /* { dg-warning "UNKNOWN" } */
      28    f.i = 2;
      29    __analyzer_eval (f.i == 2); /* { dg-warning "TRUE" } */
      30  }
      31  
      32  /* Fields of a param ptr.  */
      33  
      34  void test_3 (struct foo *f)
      35  {
      36    __analyzer_eval (f->i == 3); /* { dg-warning "UNKNOWN" } */
      37    f->i = 3;
      38    __analyzer_eval (f->i == 3); /* { dg-warning "TRUE" } */
      39  }
      40  
      41  /* Fields of a global ptr.  */
      42  struct foo *global_foo_ptr;
      43  
      44  void test_3a (void)
      45  {
      46    struct foo *tmp = global_foo_ptr;
      47    __analyzer_eval (global_foo_ptr->i == 3); /* { dg-warning "UNKNOWN" } */
      48    global_foo_ptr->i = 3;
      49    __analyzer_eval (global_foo_ptr->i == 3); /* { dg-warning "TRUE" } */
      50  }
      51  
      52  /* Pointer to a local.  */
      53  
      54  void test_4 (void)
      55  {
      56    int i;
      57    int *p = &i;
      58    i = 1;
      59    *p = 2;
      60    __analyzer_eval (i == 2); /* { dg-warning "TRUE" } */
      61  }
      62  
      63  /* Local array.  */
      64  
      65  void test_5 (void)
      66  {
      67    int a[10];
      68    a[3] = 5; /* ARRAY_REF.  */
      69    __analyzer_eval (a[3] == 5); /* { dg-warning "TRUE" } */
      70  }
      71  
      72  /* Local array, but using an unknown index.  */
      73  
      74  void test_5a (int idx)
      75  {
      76    int a[10];
      77    a[idx] = 5; /* ARRAY_REF.  */
      78    __analyzer_eval (a[idx] == 5); /* { dg-warning "TRUE" } */
      79  }
      80  
      81  /* Array passed in as a param.  */
      82  
      83  void test_6 (int a[10])
      84  {
      85    /* POINTER_PLUS_EXPR then a MEM_REF.  */
      86    __analyzer_eval (a[3] == 42); /* { dg-warning "UNKNOWN" } */
      87    a[3] = 42;
      88    __analyzer_eval (a[3] == 42); /* { dg-warning "TRUE" } */
      89  }
      90  
      91  /* Array passed in as a param ptr.  */
      92  
      93  void test_7 (int *a)
      94  {
      95    __analyzer_eval (a[3] == 42); /* { dg-warning "UNKNOWN" } */
      96    a[3] = 42;
      97    __analyzer_eval (a[3] == 42); /* { dg-warning "TRUE" } */
      98  }
      99  
     100  /* Globals.  */
     101  
     102  int glob_a;
     103  
     104  void test_10 (void)
     105  {
     106    __analyzer_eval (glob_a == 42); /* { dg-warning "UNKNOWN" } */
     107    glob_a = 42;
     108    __analyzer_eval (glob_a == 42); /* { dg-warning "TRUE" } */
     109  }
     110  
     111  /* malloc.  */
     112  
     113  void test_11 (void)
     114  {
     115    void *p = malloc (256);
     116    void *q = malloc (256);
     117  
     118    /* malloc results should be unique.  */
     119    __analyzer_eval (p == q); /* { dg-warning "FALSE" } */
     120    __analyzer_eval (p != q); /* { dg-warning "TRUE" } */
     121    __analyzer_eval (p <= q); /* { dg-warning "UNKNOWN" } */
     122    __analyzer_eval (p >= q); /* { dg-warning "UNKNOWN" } */
     123    __analyzer_eval (p < q); /* { dg-warning "UNKNOWN" } */
     124    __analyzer_eval (p > q); /* { dg-warning "UNKNOWN" } */
     125  
     126    __analyzer_eval (p == p); /* { dg-warning "TRUE" } */
     127    __analyzer_eval (p != p); /* { dg-warning "FALSE" } */
     128    __analyzer_eval (p <= p); /* { dg-warning "TRUE" } */
     129    __analyzer_eval (p >= p); /* { dg-warning "TRUE" } */
     130    __analyzer_eval (p < p); /* { dg-warning "FALSE" } */
     131    __analyzer_eval (p > p); /* { dg-warning "FALSE" } */
     132  
     133    free (p);
     134    free (q);
     135    // TODO: mark freed memory as freed
     136    //__analyzer_break ();
     137  }
     138  
     139  /* alloca.  */
     140  
     141  int test_12 (void)
     142  {
     143    void *p = __builtin_alloca (256);
     144    void *q = __builtin_alloca (256);
     145  
     146    /* alloca results should be unique.  */
     147    __analyzer_eval (p == q); /* { dg-warning "FALSE" } */
     148  
     149    return *(int *)p; /* { dg-warning "use of uninitialized value '\\*\\(int \\*\\)p" } */
     150  }
     151  
     152  /* Use of uninit value.  */
     153  int test_12a (void)
     154  {
     155    int i; /* { dg-message "region created on stack here" } */
     156    return i; /* { dg-warning "use of uninitialized value 'i'" } */
     157  }
     158  
     159  void test_12b (void *p, void *q)
     160  {
     161    __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" } */
     162  }
     163  
     164  int test_12c (void)
     165  {
     166    int i; /* { dg-message "region created on stack here" } */
     167    int j;
     168  
     169    j = i; /* { dg-warning "use of uninitialized value 'i'" } */
     170  
     171    /* We should not emit followup warnings after the first warning about
     172       an uninitialized value.  */
     173    return j; /* { dg-bogus "use of uninitialized value" } */
     174  }
     175  
     176  struct coord
     177  {
     178    long x;
     179    long y;
     180  };
     181  
     182  int test_12d (struct coord c)
     183  {
     184    struct coord d;
     185    d = c;
     186    __analyzer_eval (d.x == c.x); /* { dg-warning "TRUE" } */
     187    __analyzer_eval (d.y == c.y); /* { dg-warning "TRUE" } */
     188    __analyzer_eval (d.x == d.y); /* { dg-warning "UNKNOWN" } */
     189    /* d and c share an unknown value of type "struct coord".
     190       But d.x and d.y should be different unknown values (although they inherit
     191       from d's region).  */
     192  }
     193  
     194  /* Nested structs.  */
     195  
     196  struct outer
     197  {
     198    struct middle {
     199      struct inner {
     200        float f;
     201      } in;
     202    } mid;
     203  };
     204  
     205  void test_13 (struct outer *o)
     206  {
     207    __analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "UNKNOWN" } */
     208    o->mid.in.f = 0.f;
     209    __analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "TRUE" } */
     210  }
     211  
     212  void test_14 (struct outer o)
     213  {
     214    __analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "UNKNOWN" } */
     215    o.mid.in.f = 0.f;
     216    __analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "TRUE" } */
     217  }
     218  
     219  void test_15 (const char *str)
     220  {
     221    char ch = str[0];
     222    __analyzer_eval (ch == 'a'); /* { dg-warning "UNKNOWN" } */
     223    __analyzer_eval (ch == str[0]); /* { dg-warning "TRUE" } */
     224  
     225    ch = 'a';
     226    __analyzer_eval (ch == 'a'); /* { dg-warning "TRUE" } */
     227    __analyzer_eval (str[0] == 'a'); /* { dg-warning "UNKNOWN" } */
     228  }
     229  
     230  void test_16 (void)
     231  {
     232    const char *msg = "hello world";
     233  
     234    __analyzer_eval (msg != NULL); /* { dg-warning "TRUE" } */
     235  
     236    __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" } */
     237  
     238    __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" } */
     239  
     240    __analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */
     241  
     242    /* Out-of-bounds.  */
     243    __analyzer_eval (msg[100] == 'e'); /* { dg-warning "UNKNOWN" } */
     244    // TODO: some kind of warning for the out-of-bounds access
     245  }
     246  
     247  static const char *__attribute__((noinline))
     248  get_hello_world (void)
     249  {
     250    return "hello world";
     251  }
     252  
     253  void test_16_alt (void)
     254  {
     255    const char *msg = get_hello_world ();
     256  
     257    __analyzer_eval (msg != NULL); /* { dg-warning "TRUE" } */
     258  
     259    __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" } */
     260  
     261    __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" } */
     262  
     263    __analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */
     264  }
     265  
     266  void test_16a (const char *msg)
     267  {
     268    __analyzer_eval (strlen (msg) == 11); /* { dg-warning "UNKNOWN" } */
     269  }
     270  
     271  void test_16b (const char *msg)
     272  {
     273    __analyzer_eval (strlen (msg) == strlen (msg)); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
     274    /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
     275    // TODO(xfail)
     276  }
     277  
     278  extern int unknown_result (void);
     279  
     280  void test_16c (int i)
     281  {
     282    int j;
     283  
     284    j = i;
     285    __analyzer_eval (j == i); /* { dg-warning "TRUE" } */
     286  
     287    j = unknown_result ();
     288    __analyzer_eval (j == i); /* { dg-warning "UNKNOWN" } */
     289  }
     290  
     291  void test_16c_a (void)
     292  {
     293    int i, j;
     294  
     295    i = unknown_result ();
     296    j = unknown_result ();
     297    __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */
     298  }
     299  
     300  int global_int_16d;
     301  
     302  void test_16d (int i)
     303  {
     304    global_int_16d = i;
     305    __analyzer_eval (global_int_16d == i); /* { dg-warning "TRUE" } */
     306  
     307    global_int_16d = unknown_result ();
     308    __analyzer_eval (global_int_16d == i); /* { dg-warning "UNKNOWN" } */
     309  }
     310  
     311  extern void might_write_to (int *);
     312  
     313  void test_16e (int i)
     314  {
     315    int j;
     316  
     317    j = i;
     318    __analyzer_eval (j == i); /* { dg-warning "TRUE" } */
     319  
     320    might_write_to (&j);
     321    __analyzer_eval (j == i); /* { dg-warning "UNKNOWN" } */
     322  }
     323  
     324  void test_17 (int i)
     325  {
     326    int j = 42;
     327    __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */
     328  
     329    __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */
     330    i = j;
     331    __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
     332  }
     333  
     334  void test_18 (int i)
     335  {
     336    int j;
     337    __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
     338  
     339    j = i;
     340  
     341    __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
     342    __analyzer_eval (i >= j); /* { dg-warning "TRUE" } */
     343    __analyzer_eval (i <= j); /* { dg-warning "TRUE" } */
     344  
     345    __analyzer_eval (i != j); /* { dg-warning "FALSE" } */
     346    __analyzer_eval (i > j); /* { dg-warning "FALSE" } */
     347    __analyzer_eval (i < j); /* { dg-warning "FALSE" } */
     348  }
     349  
     350  void test_19 (void)
     351  {
     352    int i, j; /* { dg-message "region created on stack here" } */
     353    /* Compare two uninitialized locals.  */
     354      __analyzer_eval (i == j); /* { dg-warning "use of uninitialized value 'i'" "uninit i" } */
     355      /* { dg-warning "use of uninitialized value 'j'" "uninit j" { target *-*-* } .-1 } */
     356  }
     357  
     358  void test_20 (int i, int j)
     359  {
     360    __analyzer_eval (i + 1); /* { dg-warning "UNKNOWN" } */
     361    __analyzer_eval (i + j); /* { dg-warning "UNKNOWN" } */
     362  
     363    __analyzer_eval (i - 1); /* { dg-warning "UNKNOWN" } */
     364    __analyzer_eval (i - j); /* { dg-warning "UNKNOWN" } */
     365  
     366    __analyzer_eval (i * 2); /* { dg-warning "UNKNOWN" } */
     367    __analyzer_eval (i * j); /* { dg-warning "UNKNOWN" } */
     368  
     369    __analyzer_eval (i / 2); /* { dg-warning "UNKNOWN" } */
     370    __analyzer_eval (i / j); /* { dg-warning "UNKNOWN" } */
     371  
     372    __analyzer_eval (i % 2); /* { dg-warning "UNKNOWN" } */
     373    __analyzer_eval (i % j); /* { dg-warning "UNKNOWN" } */
     374  
     375    __analyzer_eval (i & 1); /* { dg-warning "UNKNOWN" } */
     376    __analyzer_eval (i & j); /* { dg-warning "UNKNOWN" } */
     377  
     378    __analyzer_eval (i | 1); /* { dg-warning "UNKNOWN" } */
     379    __analyzer_eval (i | j); /* { dg-warning "UNKNOWN" } */
     380  
     381    __analyzer_eval (i ^ 1); /* { dg-warning "UNKNOWN" } */
     382    __analyzer_eval (i ^ j); /* { dg-warning "UNKNOWN" } */
     383  
     384    __analyzer_eval (i >> 1); /* { dg-warning "UNKNOWN" } */
     385    __analyzer_eval (i >> j); /* { dg-warning "UNKNOWN" } */
     386  
     387    __analyzer_eval (i << 1); /* { dg-warning "UNKNOWN" } */
     388    __analyzer_eval (i << j); /* { dg-warning "UNKNOWN" } */
     389  
     390    __analyzer_eval (i && 0); /* { dg-warning "FALSE" } */
     391    __analyzer_eval (i && 1); /* { dg-warning "UNKNOWN" } */
     392    __analyzer_eval (i && j); /* { dg-warning "UNKNOWN" } */
     393  
     394    __analyzer_eval (i || 0); /* { dg-warning "UNKNOWN" } */
     395  
     396    __analyzer_eval (i || 1); /* { dg-warning "TRUE" } */
     397    __analyzer_eval (i || j); /* { dg-warning "UNKNOWN" } */
     398  
     399    __analyzer_eval (~i); /* { dg-warning "UNKNOWN" } */
     400    __analyzer_eval (-i); /* { dg-warning "UNKNOWN" } */
     401    __analyzer_eval (+i); /* { dg-warning "UNKNOWN" } */
     402  
     403    /* Anything added above should be added to the next function also.  */
     404  }
     405  
     406  /* As above, but where the values are known due to the region model,
     407     but not known to GCC's regular optimizations (folding and SSA).  */
     408  
     409  void test_21 (void)
     410  {
     411    int i, j, zero;
     412    int *pi = &i;
     413    int *pj = &j;
     414    int *pzero = &zero;
     415    *pi = 5;
     416    *pj = 3;
     417    *pzero = 0;
     418  
     419    __analyzer_eval (i + j == 8); /* { dg-warning "TRUE" } */
     420    __analyzer_eval (i - j == 2); /* { dg-warning "TRUE" } */
     421    __analyzer_eval (i * j == 15); /* { dg-warning "TRUE" } */
     422    __analyzer_eval (i / j == 1); /* { dg-warning "TRUE" } */
     423    __analyzer_eval (i % j == 2); /* { dg-warning "TRUE" } */
     424  
     425    /* Division by zero.  */
     426    // TODO: should we warn for this?
     427    __analyzer_eval (i / zero); /* { dg-warning "UNKNOWN" } */
     428    __analyzer_eval (i % zero); /* { dg-warning "UNKNOWN" } */
     429  
     430    __analyzer_eval ((i & 1) == (5 & 1)); /* { dg-warning "TRUE" } */
     431    __analyzer_eval ((i & j) == (5 & 3)); /* { dg-warning "TRUE" } */
     432    __analyzer_eval ((i | 1) == (5 | 1)); /* { dg-warning "TRUE" } */
     433    __analyzer_eval ((i | j) == (5 | 3)); /* { dg-warning "TRUE" } */
     434    __analyzer_eval ((i ^ 1) == (5 ^ 1)); /* { dg-warning "TRUE" } */
     435    __analyzer_eval ((i ^ j) == (5 ^ 3)); /* { dg-warning "TRUE" } */
     436    __analyzer_eval ((i >> 1) == (5 >> 1)); /* { dg-warning "TRUE" } */
     437    __analyzer_eval ((i >> j) == (5 >> 3)); /* { dg-warning "TRUE" } */
     438    __analyzer_eval ((i << 1) == (5 << 1)); /* { dg-warning "TRUE" } */
     439    __analyzer_eval ((i << j) == (5 << 3)); /* { dg-warning "TRUE" } */
     440    __analyzer_eval (i && 0); /* { dg-warning "FALSE" } */
     441    __analyzer_eval (i && 1); /* { dg-warning "TRUE" } */
     442    __analyzer_eval (i && j); /* { dg-warning "TRUE" } */
     443  
     444    __analyzer_eval (i || 0); /* { dg-warning "TRUE" } */
     445    __analyzer_eval (i || 1); /* { dg-warning "TRUE" } */
     446    __analyzer_eval (i || j); /* { dg-warning "TRUE" } */
     447  
     448    __analyzer_eval (~i == ~5); /* { dg-warning "TRUE" } */
     449    __analyzer_eval (-i == -5); /* { dg-warning "TRUE" } */
     450    __analyzer_eval (+i == +5); /* { dg-warning "TRUE" } */
     451  }
     452  
     453  void test_22 (int i, int j)
     454  {
     455    __analyzer_eval (i + j == i + j); /* { dg-warning "TRUE" } */
     456    // FIXME: this is getting folded; can we build a non-folded equivalent?
     457  }
     458  
     459  void test_23 (struct foo *f, struct foo *g)
     460  {
     461    int i, j, k;
     462    i = f->i + g->i;
     463    j = f->i + g->i;
     464    k = f->i * g->i;
     465    __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
     466    __analyzer_eval (i == k); /* { dg-warning "UNKNOWN" } */
     467  }
     468  
     469  void test_24 (struct foo *f)
     470  {
     471    struct foo g;
     472    g.i = 42;
     473    __analyzer_eval (g.i == 42); /* { dg-warning "TRUE" } */
     474  
     475    /* Overwriting a whole struct should invalidate our knowledge
     476       about fields within it.  */
     477    g = *f;
     478    __analyzer_eval (g.i == 42); /* { dg-warning "UNKNOWN" } */
     479  }
     480  
     481  void test_25 (struct foo *f)
     482  {
     483    struct foo g;
     484    g.i = 42;
     485    f->i = 43;
     486    __analyzer_eval (f->i == 43); /* { dg-warning "TRUE" } */
     487    __analyzer_eval (g.i == 42); /* { dg-warning "TRUE" } */
     488  
     489    /* Overwriting a whole struct where we know things about the
     490       source value should update our knowledge about fields within
     491       the dest value.  */
     492    g = *f;
     493    __analyzer_eval (g.i == 43); /* { dg-warning "TRUE" } */
     494  }
     495  
     496  void test_26 (struct coord *p, struct coord *q)
     497  {
     498    p->x = 42;
     499    q->y = 17; /* could clobber p->x.  */
     500    __analyzer_eval (p->x == 42); /* { dg-warning "UNKNOWN" } */
     501    __analyzer_eval (p->y); /* { dg-warning "UNKNOWN" } */
     502    __analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */
     503    __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" } */
     504  
     505    /* Overwriting a whole struct where we know some things about the
     506       source value should update our knowledge about fields within
     507       the dest value.  */
     508    *p = *q;
     509    __analyzer_eval (p->x); /* { dg-warning "UNKNOWN" } */
     510    __analyzer_eval (p->y == 17); /* { dg-warning "TRUE" } */
     511  
     512    __analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */
     513    __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
     514    /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
     515  }
     516  
     517  void test_27 (struct coord *p)
     518  {
     519    memset (p, 0, sizeof (struct coord));
     520    __analyzer_eval (p->x == 0); /* { dg-warning "TRUE" } */
     521    __analyzer_eval (p->y == 0); /* { dg-warning "TRUE" } */
     522  }
     523  
     524  void test_28 (struct coord *p)
     525  {
     526    memset (p, 0, sizeof (struct coord) * 10);
     527    __analyzer_eval (p[0].x == 0); /* { dg-warning "TRUE" } */
     528    __analyzer_eval (p[0].y == 0); /* { dg-warning "TRUE" } */
     529  
     530    __analyzer_eval (p[9].x == 0); /* { dg-warning "TRUE" } */
     531    __analyzer_eval (p[9].y == 0); /* { dg-warning "TRUE" } */
     532  
     533    __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */
     534    __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */
     535  }
     536  
     537  void test_29 (struct coord *p)
     538  {
     539    struct coord *q;
     540  
     541    p[0].x = 100024;
     542    p[0].y = 100025;
     543  
     544    p[7].x = 107024;
     545    p[7].y = 107025;
     546  
     547    p[9].x = 109024;
     548    p[9].y = 109025;
     549  
     550    __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */
     551    __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */
     552  
     553    __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */
     554    __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */
     555  
     556    __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */
     557    __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */
     558  
     559    __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */
     560    __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */
     561  
     562    q = &p[7];
     563  
     564    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     565    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     566  
     567    __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */
     568    __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */
     569  
     570    q += 2;
     571  
     572    __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */
     573    __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */
     574  
     575    __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */
     576    __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
     577  
     578    q -= 2;
     579  
     580    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     581    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     582  }
     583  
     584  void test_29a (struct coord p[])
     585  {
     586    struct coord *q;
     587  
     588    p[0].x = 100024;
     589    p[0].y = 100025;
     590  
     591    p[7].x = 107024;
     592    p[7].y = 107025;
     593  
     594    p[9].x = 109024;
     595    p[9].y = 109025;
     596  
     597    __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */
     598    __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */
     599  
     600    __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */
     601    __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */
     602  
     603    __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */
     604    __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */
     605  
     606    __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */
     607    __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */
     608  
     609    q = &p[7];
     610  
     611    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     612    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     613  
     614    __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */
     615    __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */
     616  
     617    q += 2;
     618  
     619    __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */
     620    __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */
     621  
     622    __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */
     623    __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
     624  
     625    q -= 2;
     626    __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */
     627  
     628    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     629    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     630  }
     631  
     632  void test_29b (void)
     633  {
     634    struct coord p[11]; /* { dg-message "region created on stack here" } */
     635    struct coord *q;
     636  
     637    p[0].x = 100024;
     638    p[0].y = 100025;
     639  
     640    p[7].x = 107024;
     641    p[7].y = 107025;
     642  
     643    p[9].x = 109024;
     644    p[9].y = 109025;
     645  
     646    __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */
     647    __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */
     648  
     649    __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */
     650    __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */
     651  
     652    __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */
     653    __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */
     654  
     655    q = &p[7];
     656  
     657    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     658    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     659  
     660    __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */
     661    __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */
     662  
     663    q += 2;
     664  
     665    __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */
     666    __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */
     667  
     668    __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */
     669    __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
     670  
     671    q -= 2;
     672    __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */
     673  
     674    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     675    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     676  
     677    __analyzer_eval (p[10].x == 0); /* { dg-warning "use of uninitialized value 'p\\\[10\\\].x'" } */
     678  }
     679  
     680  void test_29c (int len)
     681  {
     682    struct coord p[len];
     683    struct coord *q;
     684  
     685    p[0].x = 100024;
     686    p[0].y = 100025;
     687  
     688    p[7].x = 107024;
     689    p[7].y = 107025;
     690  
     691    p[9].x = 109024;
     692    p[9].y = 109025;
     693  
     694    __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */
     695    __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */
     696  
     697    __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */
     698    __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */
     699  
     700    __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */
     701    __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */
     702  
     703    q = &p[7];
     704  
     705    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     706    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     707  
     708    __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */
     709    __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */
     710  
     711    q += 2;
     712  
     713    __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */
     714    __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */
     715  
     716    __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */
     717    __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
     718  
     719    q -= 2;
     720    __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */
     721  
     722    __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
     723    __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
     724  
     725    __analyzer_eval (p[10].x == 0); /* { dg-warning "use of uninitialized value '\\*p\\\[10\\\].x'" } */
     726  }
     727  
     728  void test_30 (void *ptr)
     729  {
     730    struct coord *p = (struct coord *)ptr;
     731    struct coord *q = (struct coord *)ptr;
     732  
     733    p->x = 42;
     734  
     735    __analyzer_eval (p->x == 42); /* { dg-warning "TRUE" } */
     736    __analyzer_eval (q->x == 42); /* { dg-warning "TRUE" } */
     737  }
     738  
     739  void test_31 (unsigned i)
     740  {
     741    int j, k;
     742  
     743    j = i < 100 ? i : 100; /* MIN_EXPR.  */
     744    k = i < 100 ? 100 : i; /* MAX_EXPR.  */
     745  }
     746  
     747  enum color
     748  {
     749    RED,
     750    GREEN,
     751    BLUE
     752  };
     753  
     754  void test_32 (enum color c)
     755  {
     756    __analyzer_eval (c == GREEN); /* { dg-warning "UNKNOWN" } */
     757  
     758    c = RED;
     759  
     760    __analyzer_eval (c == RED); /* { dg-warning "TRUE" } */
     761    __analyzer_eval (c == GREEN); /* { dg-warning "FALSE" } */
     762  }
     763  
     764  void test_33 (void)
     765  {
     766    static int s;
     767  
     768    __analyzer_eval (s == 42); /* { dg-warning "UNKNOWN" } */
     769  
     770    s = 42;
     771  
     772    __analyzer_eval (s == 42); /* { dg-warning "TRUE" } */
     773  }
     774  
     775  static int __attribute__((noinline))
     776  __analyzer_only_called_by_test_34 (int parm)
     777  {
     778    __analyzer_eval (parm == 42); /* { dg-warning "TRUE" } */
     779  
     780    return parm * 2;
     781  }
     782  
     783  void test_34 (void)
     784  {
     785    int result = __analyzer_only_called_by_test_34 (42);
     786    __analyzer_eval (result == 84); /* { dg-warning "TRUE" } */
     787  }
     788  
     789  void test_35 (int i, int j)
     790  {
     791    __analyzer_eval (&i == &i); /* { dg-warning "TRUE" } */
     792    __analyzer_eval (&i != &j); /* { dg-warning "TRUE" } */
     793  }
     794  
     795  static void __attribute__((noinline))
     796  write_through_ptr (int *dst, int val)
     797  {
     798    *dst = val;
     799  }
     800  
     801  void test_36 (int i)
     802  {
     803    __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
     804  
     805    write_through_ptr (&i, 42);
     806  
     807    __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
     808  }
     809  
     810  /* Read through uninitialized pointer.  */
     811  
     812  int test_37 (void)
     813  {
     814    int *ptr; /* { dg-message "region created on stack here" } */
     815    return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */
     816  }
     817  
     818  /* Write through uninitialized pointer.  */
     819  
     820  void test_37a (int i)
     821  {
     822    int *ptr; /* { dg-message "region created on stack here" } */
     823    *ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" } */
     824  }
     825  
     826  // TODO: the various other ptr deref poisonings
     827  
     828  /* Read through NULL pointer.  */
     829  
     830  int test_38 (void)
     831  {
     832    int *ptr = NULL;
     833    return *ptr; /* { dg-warning "dereference of NULL 'ptr'" } */
     834  }
     835  
     836  /* Write through NULL pointer.  */
     837  
     838  int test_38a (int i)
     839  {
     840    int *ptr = NULL;
     841    *ptr = i; /* { dg-warning "dereference of NULL 'ptr'" } */
     842  }
     843  
     844  /* Read through non-NULL constant pointer.  */
     845  
     846  int test_39 (void)
     847  {
     848    int *ptr = (int *)0x1000;
     849    return *ptr;
     850  }
     851  
     852  int test_40 (int flag)
     853  {
     854    int i;
     855    if (flag)
     856      i = 43;
     857    else
     858      i = 17;
     859  
     860    /* With state-merging, we lose the relationship between 'flag' and 'i'.  */
     861    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
     862  
     863    if (flag)
     864      __analyzer_eval (i == 43); /* { dg-warning "UNKNOWN" } */
     865    else
     866      __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
     867  }
     868  
     869  struct link
     870  {
     871    struct link *next;
     872    int f;
     873  };
     874  
     875  /* Traversing a singly-linked list.  */
     876  
     877  void foo (struct link *in)
     878  {
     879    struct link a;
     880    struct link b;
     881    struct link c;
     882    a.next = &b;
     883    b.next = &c;
     884    in->next = &a;
     885    c.f = 42;
     886    __analyzer_eval (in->next->next->next->f == 42);  /* { dg-warning "TRUE" } */
     887  }
     888  
     889  union u
     890  {
     891    int i;
     892    int *ptr;
     893  };
     894  
     895  void test_41 (void)
     896  {
     897    union u u;
     898    u.i = 42;
     899    __analyzer_eval (u.i == 42); /* { dg-warning "TRUE" } */
     900    __analyzer_eval (u.ptr == NULL); /* { dg-warning "UNKNOWN|FALSE" } */
     901  
     902    /* Writes to a union member should invalidate knowledge about other members.  */
     903    u.ptr = NULL;
     904    __analyzer_eval (u.ptr == NULL); /* { dg-warning "TRUE" } */
     905    __analyzer_eval (u.i == 42); /* { dg-warning "UNKNOWN|FALSE" } */
     906  }
     907  
     908  void test_42 (void)
     909  {
     910    int i;
     911    float f;
     912    i = 42;
     913    f = i;
     914    __analyzer_eval (f == 42.0); /* { dg-warning "TRUE" } */
     915  }
     916  
     917  void test_43 (void)
     918  {
     919    int i;
     920    float f;
     921    f = 42.0f;
     922    i = f;
     923    __analyzer_eval (i == 42);  /* { dg-warning "TRUE" } */
     924  }
     925  
     926  struct sbits
     927  {
     928    signed int b0 : 1;
     929    signed int b123 : 3;
     930    signed int b456 : 3;
     931    signed int b7 : 1;
     932  };
     933  
     934  void test_44 (void)
     935  {
     936    struct sbits bits;
     937    bits.b0 = -1;
     938    __analyzer_eval (bits.b0 == -1); /* { dg-warning "TRUE" } */
     939  
     940    bits.b456 = -4;
     941    __analyzer_eval (bits.b456 == -4); /* { dg-warning "TRUE" } */
     942  };
     943  
     944  struct ubits
     945  {
     946    unsigned int b0 : 1;
     947    unsigned int b123 : 3;
     948    unsigned int b456 : 3;
     949    unsigned int b7 : 1;
     950  };
     951  
     952  void test_45 (void)
     953  {
     954    struct ubits bits;
     955    bits.b0 = 1;
     956    __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" } */
     957  
     958    bits.b456 = 5;
     959    __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" } */
     960  };
     961  
     962  extern const char *char_ptr;
     963  
     964  int test_46 (void)
     965  {
     966    if (strcmp("literal", char_ptr))
     967      return 1;
     968    return 0;
     969  }
     970  
     971  char test_47 (void)
     972  {
     973    static const char* my_version = "1.1.3";
     974    return my_version[0];
     975  }
     976  
     977  unsigned test_48 (unsigned char *p, unsigned char *q)
     978  {
     979    return (unsigned int)(p - q);
     980  }
     981  
     982  typedef struct {
     983    const char *filename;
     984    short lineno;
     985  } loc;
     986  
     987  static loc loc_last;
     988  
     989  void test_49 (void)
     990  {
     991    loc_last = __extension__(loc) { "", 328 };
     992    loc_last = __extension__(loc) { "", 333 };
     993  }
     994  
     995  void test_50 (void *p, void *q)
     996  {
     997    __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" } */
     998    __analyzer_eval (p == p); /* { dg-warning "TRUE" } */
     999    __analyzer_eval (q == q); /* { dg-warning "TRUE" } */
    1000    __analyzer_eval (p == (struct coord *)p); /* { dg-warning "TRUE" } */
    1001    __analyzer_eval (p == (const struct coord *)p); /* { dg-warning "TRUE" } */
    1002  
    1003    struct coord *cp = (struct coord *)p;
    1004    __analyzer_eval (p == cp); /* { dg-warning "TRUE" } */
    1005  
    1006    struct coord *cq = (struct coord *)q;
    1007    __analyzer_eval (q == cq); /* { dg-warning "TRUE" } */
    1008  
    1009    __analyzer_eval (cp == cq); /* { dg-warning "UNKNOWN" } */
    1010  }
    1011  
    1012  void test_51 (struct coord c)
    1013  {
    1014    struct coord d;
    1015    memcpy (&d, &c, sizeof (struct coord));
    1016    __analyzer_eval (c.x == d.x); /* { dg-warning "TRUE" } */
    1017    __analyzer_eval (c.y == d.y); /* { dg-warning "TRUE" } */
    1018  }
    1019  
    1020  struct big
    1021  {
    1022    int ia[1024];  
    1023  };
    1024  
    1025  void test_52 (struct big b)
    1026  {
    1027    struct big d;
    1028    memcpy (&d, &b, sizeof (struct big));
    1029    __analyzer_eval (b.ia[0] == d.ia[0]); /* { dg-warning "TRUE" } */
    1030    __analyzer_eval (b.ia[1023] == d.ia[1023]); /* { dg-warning "TRUE" } */
    1031  }
    1032  
    1033  void test_53 (const char *msg)
    1034  {
    1035    (void)fprintf(stderr, "LOG: %s", msg);
    1036  }