1  /* PR tree-optimization/97027 - missing warning on buffer overflow storing
       2     a larger scalar into a smaller array
       3     Verify warnings for overflow by stores of results of built-in functions.
       4     { dg-do compile }
       5     { dg-options "-O2" }
       6     { dg-require-effective-target alloca } */
       7  
       8  typedef __INT16_TYPE__ int16_t;
       9  typedef __SIZE_TYPE__  size_t;
      10  
      11  extern int abs (int);
      12  
      13  extern void* alloca (size_t);
      14  
      15  extern double nan (const char *);
      16  
      17  #ifdef __DEC32_MAX__
      18    _Decimal32 nand32 (const char *);
      19  #else
      20  /* _Decimal32 is supported only conditionally and not available on all
      21     targets.  */
      22  #  define _Decimal32  double
      23  #  define nand32(s)   nan (s)
      24  #endif
      25  
      26  extern size_t strlen (const char *);
      27  extern char* strcpy (char *, const char *);
      28  
      29  
      30  extern unsigned char ax[], a1[1], a2[2], a8[8];
      31  
      32  
      33  void nowarn_abs (int i)
      34  {
      35    *(int *)ax = abs (i);
      36    *(char *)a1 = abs (i);
      37  }
      38  
      39  void warn_abs (int i)
      40  {
      41    *(int *)a1 = abs (i);         // { dg-warning "\\\[-Wstringop-overflow" }
      42  }
      43  
      44  
      45  void nowarn_alloca (size_t n)
      46  {
      47    *(void **)ax = alloca (n);
      48  }
      49  
      50  void warn_alloca (size_t n)
      51  {
      52    *(void **)a1 = alloca (n);    // { dg-warning "\\\[-Wstringop-overflow" }
      53  }
      54  
      55  
      56  void nowarn_complex (double x, double i)
      57  {
      58    *(_Complex double *)ax = __builtin_complex (x, i);
      59  }
      60  
      61  void warn_complex (double x, double i)
      62  {
      63    _Complex double *p = (_Complex double *)a1;
      64    *p = __builtin_complex (x, i);  // { dg-warning "\\\[-Wstringop-overflow" "pr101455" { xfail *-*-* } }
      65  }
      66  
      67  
      68  __attribute__ ((noipa)) void nowarn_nan (const char *s)
      69  {
      70    *(double *)ax = nan (s);
      71  }
      72  
      73  __attribute__ ((noipa)) void warn_nan (const char *s)
      74  {
      75    *(double *)a1 = nan (s);      // { dg-warning "\\\[-Wstringop-overflow" }
      76  }
      77  
      78  
      79  __attribute__ ((noipa)) void nowarn_nand32 (const char *s)
      80  {
      81    *(_Decimal32 *)ax = nand32 (s);
      82  }
      83  
      84  __attribute__ ((noipa)) void warn_nand32 (const char *s)
      85  {
      86    *(_Decimal32 *)a1 = nand32 (s); // { dg-warning "\\\[-Wstringop-overflow" }
      87  }
      88  
      89  
      90  void nowarn_strlen (const char *s1, const char *s2, const char *s3)
      91  {
      92    *(char *)ax = strlen (s1);
      93    *(char *)a1 = strlen (s2);
      94    *(size_t *)a8 = strlen (s3);
      95  }
      96  
      97  void warn_strlen (const char *s1, const char *s2)
      98  {
      99    *(int16_t *)a1 = strlen (s1); // { dg-warning "\\\[-Wstringop-overflow" }
     100    *(size_t *)a2 = strlen (s2);  // { dg-warning "\\\[-Wstringop-overflow" "!ptr_eq_short" { target { ! ptr_eq_short } } }
     101  }
     102  
     103  
     104  void nowarn_strcpy (char *s1, char *s2, const char *s3)
     105  {
     106    *(char **)ax = strcpy (s1, s2);
     107    *(char **)a8 = strcpy (s2, s3);
     108  }
     109  
     110  void warn_strcpy (char *s1, char *s2, const char *s3)
     111  {
     112    *(char **)a1 = strcpy (s1, s2);   // { dg-warning "\\\[-Wstringop-overflow" }
     113    *(char **)a2 = strcpy (s2, s3);   // { dg-warning "\\\[-Wstringop-overflow" "!ptr_eq_short" { target { ! ptr_eq_short } } }
     114  }