(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Warray-bounds-4.c
       1  /* Exercise that -Warray-bounds is issued for out-of-bounds offsets
       2     in calls to built-in functions.
       3     { dg-do compile }
       4     { dg-options "-O2 -Warray-bounds=2 -Wno-stringop-overflow -ftrack-macro-expansion=0" }  */
       5  
       6  #include "../gcc.dg/range.h"
       7  
       8  #if __cplusplus
       9  #  define restrict __restrict
      10  extern "C" {
      11  #endif
      12  
      13  extern void* memcpy (void* restrict, const void* restrict, size_t);
      14  extern void* mempcpy (void* restrict, const void* restrict, size_t);
      15  extern void* memmove (void*, const void*, size_t);
      16  
      17  extern char* stpcpy (char* restrict, const char* restrict);
      18  
      19  extern char* strcat (char* restrict, const char* restrict);
      20  extern char* strcpy (char* restrict, const char* restrict);
      21  extern char* strncpy (char* restrict, const char* restrict, size_t);
      22  
      23  #if __cplusplus
      24  }   /* extern "C" */
      25  #endif
      26  
      27  struct MA { char a5[5], a7[7]; };
      28  
      29  void sink (void*, ...);
      30  
      31  void test_memcpy_bounds_memarray_range (void)
      32  {
      33  #undef TM
      34  #define TM(mem, dst, src, n)			\
      35    do {						\
      36      struct MA ma;				\
      37      sink (&ma);   /* Initialize arrays.  */	\
      38      memcpy (dst, src, n);			\
      39      sink (&ma);					\
      40    } while (0)
      41  
      42    ptrdiff_t j = SR (1, 2);
      43  
      44    TM (ma.a5, ma.a5 + j, ma.a5, 1);
      45    TM (ma.a5, ma.a5 + j, ma.a5, 3);
      46  
      47    /* The copy below is invalid for two reasons: 1) it overlaps and 2) it
      48       writes past the end of ma.a5.  The warning is a little cryptic here
      49       because the GIMPLE is:
      50         _4 = &ma.a5 + prephitmp_14;
      51         MEM <unsigned char[5]> [(char * {ref-all})_4]
      52           = MEM <unsigned char[5]> [(char * {ref-all})&ma];
      53       and could be improved.  Just verify that one is issued but not its
      54       full text.  */
      55    TM (ma.a5, ma.a5 + j, ma.a5, 5);        /* { dg-warning "\\\[-Warray-bounds" "pr101374" { xfail *-*-* } } */
      56  
      57    TM (ma.a5, ma.a5 + j, ma.a5, 7);        /* { dg-warning "offset \\\[5, 7] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
      58    TM (ma.a5, ma.a5 + j, ma.a5, 9);        /* { dg-warning "offset \\\[5, 9] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
      59  }
      60  
      61  #if __i386__ || __x86_64__
      62  
      63  /* Disabled for non-x86 targets due to bug 83543.  */
      64  
      65  void test_strcpy_bounds_memarray_range (void)
      66  {
      67  #undef TM
      68  #define TM(a5init, a7init, dst, src)		\
      69    do {						\
      70      struct MA ma = { a5init, a7init };		\
      71      strcpy (dst, src);				\
      72      sink (&ma);					\
      73    } while (0)
      74  
      75    ptrdiff_t i = SR (1, 2);
      76  
      77    TM ("0", "",     ma.a5 + i, ma.a5);
      78    TM ("01", "",    ma.a5 + i, ma.a5);
      79    TM ("012", "",   ma.a5 + i, ma.a5);
      80    TM ("0123", "",  ma.a5 + i, ma.a5);     /* { dg-warning "offset 5 from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char *\\\[5]. at offset 0" "pr83543" { xfail { ! { i?86-*-* x86_64-*-* } } } } */
      81  
      82    TM ("", "012345", ma.a7 + i, ma.a7);    /* { dg-warning "offset 12 from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a7. with type .char ?\\\[7]. at offset 5" "pr83543" { xfail { ! { i?86-*-* x86_64-*-* } } } } */
      83  }
      84  #endif