view gcc/testsuite/c-c++-common/attr-nonstring-2.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents
children
line wrap: on
line source

/* Test to exercise attribute "nonstring".
   { dg-do compile }
   { dg-options "-O2 -Wattributes -Wstringop-truncation -ftrack-macro-expansion=0" }  */

#define ATTR(list) __attribute__ (list)
#define NONSTR     ATTR ((nonstring))
#define strncpy(d, s, n) (__builtin_strncpy ((d), (s), (n)), sink (d))

void sink (void*);

/* Global string with an unknown bound.  */
extern char gsx[];

/* Global string with an known bound.  */
extern char gs3[3];

/* Global non-strings with an unknown bound.  */
extern NONSTR char gax_1[];
extern char NONSTR gax_2[];
extern char gax_3[] NONSTR;

/* Global non-strings with a known bound.  */
NONSTR char gns3[3];
char NONSTR gns4[4];
char gns5[5] NONSTR;

/* Global string pointer.  */
extern char *ps_1;

/* Global non-string pointers.  */
extern NONSTR char *pns_1;
extern char* NONSTR pns_2;
extern char *pns_3 NONSTR;

struct MemArrays
{
  NONSTR char ma3[3];
  char NONSTR ma4[4];
  char ma5[5] NONSTR;
  char max[] NONSTR;
};


void test_array (const char *s, unsigned n)
{
  const char s7[] = "1234567";

  strncpy (gs3, "", 0);           /* { dg-warning "destination unchanged after copying no bytes" } */
  strncpy (gs3, "a", 1);          /* { dg-warning "output truncated before terminating nul copying 1 byte from a string of the same length" } */
  strncpy (gs3, "a", 2);
  strncpy (gs3, "a", 3);
  strncpy (gs3, "ab", 3);
  strncpy (gs3, "abc", 3);        /* { dg-warning "output truncated before terminating nul copying 3 bytes from a string of the same length" } */

  /* It might perhaps be helpful to diagnose certain truncation even
     for non-strings.  Then again, since the destination has been
     explicitly annotated as non-string, it might be viewed as a false
     positive.  A valid use case seen in Glibc goes something like this:

     #if FOO
     # define S "1234"
     #else
     # define S "12345678"
     #endif

     strncpy (d, S, 8);
  */
  strncpy (gax_3, s7, 3);

  strncpy (gax_1, "a", 1);
  strncpy (gax_2, "ab", 2);
  strncpy (gax_3, "abc", 3);
  strncpy (gax_3, s7, 3);

  strncpy (gax_1, s, 1);
  strncpy (gax_2, s, 1);
  strncpy (gax_3, s, 1);

  strncpy (gax_1, s, n);
  strncpy (gax_2, s, n);
  strncpy (gax_3, s, n);
}


void test_pointer (const char *s, unsigned n)
{
  const char s7[] = "1234567";

  strncpy (pns_1, "a", 1);
  strncpy (pns_2, "ab", 2);
  strncpy (pns_3, "abc", 3);
  strncpy (pns_3, s7, 3);

  strncpy (pns_1, s, 1);
  strncpy (pns_2, s, 1);
  strncpy (pns_3, s, 1);

  strncpy (pns_1, s, n);
  strncpy (pns_2, s, n);
  strncpy (pns_3, s, n);
}


void test_member_array (struct MemArrays *p, const char *s, unsigned n)
{
  const char s7[] = "1234567";

  strncpy (p->ma3, "", 0);
  strncpy (p->ma3, "a", 1);
  strncpy (p->ma4, "ab", 2);
  strncpy (p->ma5, "abc", 3);
  strncpy (p->max, "abcd", 4);
  strncpy (p->max, s7, 5);

  strncpy (p->ma3, s, 1);
  strncpy (p->ma4, s, 1);
  strncpy (p->ma5, s, 1);
  strncpy (p->max, s, 1);

  strncpy (p->ma3, s7, n);
  strncpy (p->ma4, s7, n);
  strncpy (p->ma5, s7, n);
  strncpy (p->max, s7, n);
}