1  /* Test to verify that past-the-end multibyte writes via lvalues of wider
       2     types than char are diagnosed.
       3     { dg-do compile }
       4     { dg-require-effective-target int32plus }
       5     { dg-options "-O2 -Wall -Wno-array-bounds" }
       6     { dg-additional-options "-mtune=generic" { target { i?86-*-* x86_64-*-* } } } */
       7  
       8  typedef __INT16_TYPE__  int16_t;
       9  typedef __INT32_TYPE__  int32_t;
      10  typedef __INT64_TYPE__  int64_t;
      11  typedef __SIZE_TYPE__   size_t;
      12  
      13  void* memcpy (void*, const void*, size_t);
      14  char* strcpy (char*, const char*);
      15  
      16  char a4[4], a8[8], a16[16];
      17  
      18  const char s4[] = "1234";
      19  const char t4[] = "4321";
      20  
      21  void test_memcpy_cond (int i)
      22  {
      23    char *p = a4 + 1;
      24    const char *q = i ? s4 : t4;
      25    // On strictly aligned target the call below is left unchanged and
      26    // triggers (inaccurately) a -Warray-bounds.  The test suppresses
      27    // the warning above, which then lets -Wstringop-overrflow detect
      28    // the overflow just before expansion.
      29    // On other targets it's transformed into a store of a 4-byte integer
      30    // which is detected by -Wstringop-overrflow in the strlen pass (i.e.,
      31    // before it gets to expansion).
      32    memcpy (p, q, 4);         // { dg-warning "writing 4 bytes into a region of size 3" }
      33  }
      34  
      35  
      36  void test_int16 (void)
      37  {
      38    char *p = a4 + 1;
      39    *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "pr102706" { target { vect_slp_v2hi_store_unalign } } }
      40    *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "pr102706" { xfail { vect_slp_v2hi_store_unalign } } }
      41  }
      42  
      43  
      44  void test_int32 (void)
      45  {
      46    char *p = a8 + 3;
      47    *(int32_t*)p = 0;
      48    *(int32_t*)(p + 2) = 0;   // { dg-warning "writing 4 bytes into a region of size 3" }
      49  }
      50  
      51  
      52  void test_int64 (void)
      53  {
      54    char *p = a16 + 5;
      55    *(int64_t*)p = 0;
      56    *(int64_t*)(p + 5) = 0;   // { dg-warning "writing 8 bytes into a region of size 6" }
      57  }