1  #include <string.h>
       2  #include "analyzer-decls.h"
       3  
       4  /* Zero-fill of uninitialized buffer.  */
       5  
       6  void test_1 (void)
       7  {
       8    char buf[256];
       9    memset (buf, 0, 256);
      10    __analyzer_eval (buf[42] == 0); /* { dg-warning "TRUE" } */
      11  }
      12  
      13  /* As above, but with __builtin_memset.  */
      14  
      15  void test_1a (void)
      16  {
      17    char buf[256];
      18    __builtin_memset (buf, 0, 256);
      19    __analyzer_eval (buf[42] == 0); /* { dg-warning "TRUE" } */
      20  }
      21  
      22  /* Zero-fill of partially initialized buffer.  */
      23  
      24  void test_2 (void)
      25  {
      26    char buf[256];
      27    buf[42] = 'A';
      28    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
      29    memset (buf, 0, 256);
      30    __analyzer_eval (buf[42] == '\0'); /* { dg-warning "TRUE" } */
      31  }
      32  
      33  /* A "memset" with known non-zero value.  */
      34  
      35  void test_3 (int val)
      36  {
      37    char buf[256];
      38    memset (buf, 'A', 256);
      39    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
      40  }
      41  
      42  /* A "memset" with unknown value.  */
      43  
      44  void test_4 (char val)
      45  {
      46    char buf[256];
      47    memset (buf, val, 256);
      48    __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" } */
      49  }
      50  
      51  /* A "memset" with unknown num bytes.  */
      52  
      53  void test_5 (int n)
      54  {
      55    char buf[256];
      56    buf[42] = 'A';
      57    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
      58    memset (buf, 0, n);
      59  
      60    /* We can't know if buf[42] was written to or not.  */
      61    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */
      62    __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */
      63  }
      64  
      65  /* As test_5, but with "__builtin___memset_chk".  */
      66  
      67  void test_5a (int n)
      68  {
      69    char buf[256];
      70    buf[42] = 'A';
      71    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
      72    __builtin___memset_chk (buf, 0, n, __builtin_object_size (buf, 0));
      73  
      74    /* We can't know if buf[42] was written to or not.  */
      75    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */
      76    __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */
      77  }
      78  
      79  /* A "memset" with unknown value, but with zero size.  */
      80  
      81  static size_t __attribute__((noinline))
      82  get_zero (void)
      83  {
      84    return 0;
      85  }
      86  
      87  void test_6 (int val)
      88  {
      89    char buf[256];
      90    buf[42] = 'A';
      91    memset (buf, 'B', get_zero ());
      92    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */  
      93  }
      94  
      95  void test_6b (int val)
      96  {
      97    char buf[256];
      98    memset (buf, 'A', sizeof (buf));
      99    memset (buf, 'B', get_zero ());
     100    __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */  
     101  }
     102  
     103  /* A "memset" of known size that's not the full buffer.  */
     104  
     105  void test_7 (void)
     106  {
     107    char buf[256];
     108    buf[128] = 'A';
     109    memset (buf, 0, 128);
     110    __analyzer_eval (buf[0] == '\0'); /* { dg-warning "TRUE" } */
     111    __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" } */
     112    __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" } */
     113  }
     114  
     115  void test_8 (void)
     116  {
     117    char buf[20];
     118    memset (buf + 0, 0, 1);
     119    memset (buf + 1, 1, 1);
     120    memset (buf + 2, 2, 1);
     121    memset (buf + 3, 3, 1);
     122    memset (buf + 4, 4, 2);
     123    memset (buf + 6, 6, 2);
     124    memset (buf + 8, 8, 4);
     125    memset (buf + 12, 12, 8);
     126    __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
     127    __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
     128    __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */
     129    __analyzer_eval (buf[3] == 3); /* { dg-warning "TRUE" } */
     130    __analyzer_eval (buf[4] == 4); /* { dg-warning "TRUE" } */
     131    __analyzer_eval (buf[5] == 4); /* { dg-warning "TRUE" } */
     132    __analyzer_eval (buf[6] == 6); /* { dg-warning "TRUE" } */
     133    __analyzer_eval (buf[7] == 6); /* { dg-warning "TRUE" } */
     134    __analyzer_eval (buf[8] == 8); /* { dg-warning "TRUE" } */
     135    __analyzer_eval (buf[9] == 8); /* { dg-warning "TRUE" } */
     136    __analyzer_eval (buf[10] == 8); /* { dg-warning "TRUE" } */
     137    __analyzer_eval (buf[11] == 8); /* { dg-warning "TRUE" } */
     138    __analyzer_eval (buf[12] == 12); /* { dg-warning "TRUE" } */
     139    __analyzer_eval (buf[13] == 12); /* { dg-warning "TRUE" } */
     140    __analyzer_eval (buf[14] == 12); /* { dg-warning "TRUE" } */
     141    __analyzer_eval (buf[15] == 12); /* { dg-warning "TRUE" } */
     142    __analyzer_eval (buf[16] == 12); /* { dg-warning "TRUE" } */
     143    __analyzer_eval (buf[17] == 12); /* { dg-warning "TRUE" } */
     144    __analyzer_eval (buf[18] == 12); /* { dg-warning "TRUE" } */
     145    __analyzer_eval (buf[19] == 12); /* { dg-warning "TRUE" } */
     146  }
     147  
     148  /* Various overlapping memset calls with different sizes and values.  */
     149  
     150  void test_9 (void)
     151  {
     152    char buf[8];
     153    memset (buf, 0, 8);
     154    __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
     155    __analyzer_eval (buf[1] == 0); /* { dg-warning "TRUE" } */
     156    __analyzer_eval (buf[2] == 0); /* { dg-warning "TRUE" } */
     157    __analyzer_eval (buf[3] == 0); /* { dg-warning "TRUE" } */
     158    __analyzer_eval (buf[4] == 0); /* { dg-warning "TRUE" } */
     159    __analyzer_eval (buf[5] == 0); /* { dg-warning "TRUE" } */
     160    __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */
     161    __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
     162  
     163    memset (buf + 1, 1, 4);  
     164    __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
     165    __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
     166    __analyzer_eval (buf[2] == 1); /* { dg-warning "TRUE" } */
     167    __analyzer_eval (buf[3] == 1); /* { dg-warning "TRUE" } */
     168    __analyzer_eval (buf[4] == 1); /* { dg-warning "TRUE" } */
     169    __analyzer_eval (buf[5] == 0); /* { dg-warning "TRUE" } */
     170    __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */
     171    __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
     172  
     173    memset (buf + 2, 2, 4);  
     174    __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
     175    __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
     176    __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */
     177    __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */
     178    __analyzer_eval (buf[4] == 2); /* { dg-warning "TRUE" } */
     179    __analyzer_eval (buf[5] == 2); /* { dg-warning "TRUE" } */
     180    __analyzer_eval (buf[6] == 0); /* { dg-warning "TRUE" } */
     181    __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
     182  
     183    memset (buf + 4, 3, 3);  
     184    __analyzer_eval (buf[0] == 0); /* { dg-warning "TRUE" } */
     185    __analyzer_eval (buf[1] == 1); /* { dg-warning "TRUE" } */
     186    __analyzer_eval (buf[2] == 2); /* { dg-warning "TRUE" } */
     187    __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */
     188    __analyzer_eval (buf[4] == 3); /* { dg-warning "TRUE" } */
     189    __analyzer_eval (buf[5] == 3); /* { dg-warning "TRUE" } */
     190    __analyzer_eval (buf[6] == 3); /* { dg-warning "TRUE" } */
     191    __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
     192  
     193    memset (buf + 0, 4, 3);  
     194    __analyzer_eval (buf[0] == 4); /* { dg-warning "TRUE" } */
     195    __analyzer_eval (buf[1] == 4); /* { dg-warning "TRUE" } */
     196    __analyzer_eval (buf[2] == 4); /* { dg-warning "TRUE" } */
     197    __analyzer_eval (buf[3] == 2); /* { dg-warning "TRUE" } */
     198    __analyzer_eval (buf[4] == 3); /* { dg-warning "TRUE" } */
     199    __analyzer_eval (buf[5] == 3); /* { dg-warning "TRUE" } */
     200    __analyzer_eval (buf[6] == 3); /* { dg-warning "TRUE" } */
     201    __analyzer_eval (buf[7] == 0); /* { dg-warning "TRUE" } */
     202  }