1  /* PR 85643 - attribute nonstring fails to squash -Wstringop-truncation
       2     warning
       3    { dg-do compile }
       4    { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
       5  
       6  #define strncpy   __builtin_strncpy
       7  
       8  struct A {
       9    char a[16 + 1];
      10  };
      11  
      12  struct B {
      13    char a[16] __attribute__ ((__nonstring__));
      14  };
      15  
      16  struct B*
      17  test_memarray (const struct A *s)
      18  {
      19    static struct B b;
      20    strncpy (b.a, s->a, sizeof b.a);
      21    return &b;
      22  }
      23  
      24  const char*
      25  test_array (const char *s)
      26  {
      27    static char a[80] __attribute__ ((__nonstring__));
      28    strncpy (a, s, sizeof a);
      29    return a;
      30  }
      31  
      32  const char*
      33  test_array_idx (const char *s)
      34  {
      35    static char a[80]  __attribute__ ((__nonstring__));
      36    char *p __attribute__ ((__nonstring__)) = &a[20];
      37    strncpy (p, s, 60);   /* { dg-bogus "-Wstringop-truncation" } */
      38    return a;
      39  }
      40  
      41  const char*
      42  test_array_off (const char *s)
      43  {
      44    static char a[80]  __attribute__ ((__nonstring__));
      45    char *p __attribute__ ((__nonstring__)) = a + 20;
      46    strncpy (p, s, 60);   /* { dg-bogus "-Wstringop-truncation" } */
      47    return a;
      48  }
      49  
      50  struct B*
      51  test_memarray_cstidx_idx (const char *s)
      52  {
      53    static struct B b[2];
      54    char *p __attribute__ ((__nonstring__)) = &b[1].a[4];
      55  
      56    /* The destination below is represented as &MEM[(void *)&a + 20B] and
      57       which (in general) doesn't make it possible to determine what member
      58       it refers to.  */
      59    strncpy (p, s, sizeof b[1].a - 4);   /* { dg-bogus "-Wstringop-truncation" "" { xfail *-*-*} } */
      60    return b;
      61  }
      62  
      63  struct B*
      64  test_memarray_cstidx_off (const char *s)
      65  {
      66    static struct B b[2];
      67    char *p __attribute__ ((__nonstring__)) = b[1].a + 4;
      68  
      69    /* Same as above.  */
      70    strncpy (p, s, sizeof b[1].a - 4);   /* { dg-bogus "-Wstringop-truncation" "" { xfail *-*-*} } */
      71    return b;
      72  }
      73  
      74  struct B*
      75  test_memarray_varidx_idx (const char *s, int i)
      76  {
      77    static struct B b[3];
      78    char *p __attribute__ ((__nonstring__)) = &b[i].a[4];
      79    strncpy (p, s, sizeof b[i].a - 4);
      80    return b;
      81  }
      82  
      83  struct B*
      84  test_memarray_varidx_off (const char *s, int i)
      85  {
      86    static struct B b[3];
      87    char *p __attribute__ ((__nonstring__)) = b[i].a + 4;
      88    strncpy (p, s, sizeof b[i].a - 4);
      89    return b;
      90  }