PR tree-optimization/86401
[official-gcc.git] / gcc / testsuite / c-c++-common / attr-nonstring-2.c
blob67fce0375d8d4f645b08dd161bfbf1d3abc4553c
1 /* Test to exercise attribute "nonstring".
2 { dg-do compile }
3 { dg-options "-O2 -Wattributes -Wstringop-truncation -ftrack-macro-expansion=0" } */
5 #define ATTR(list) __attribute__ (list)
6 #define NONSTR ATTR ((nonstring))
7 #define strncpy(d, s, n) (__builtin_strncpy ((d), (s), (n)), sink (d))
9 void sink (void*);
11 /* Global string with an unknown bound. */
12 extern char gsx[];
14 /* Global string with an known bound. */
15 extern char gs3[3];
17 /* Global non-strings with an unknown bound. */
18 extern NONSTR char gax_1[];
19 extern char NONSTR gax_2[];
20 extern char gax_3[] NONSTR;
22 /* Global non-strings with a known bound. */
23 NONSTR char gns3[3];
24 char NONSTR gns4[4];
25 char gns5[5] NONSTR;
27 /* Global string pointer. */
28 extern char *ps_1;
30 /* Global non-string pointers. */
31 extern NONSTR char *pns_1;
32 extern char* NONSTR pns_2;
33 extern char *pns_3 NONSTR;
35 struct MemArrays
37 NONSTR char ma3[3];
38 char NONSTR ma4[4];
39 char ma5[5] NONSTR;
40 char max[] NONSTR;
44 void test_array (const char *s, unsigned n)
46 const char s7[] = "1234567";
48 strncpy (gs3, "", 0); /* { dg-warning "destination unchanged after copying no bytes" } */
49 strncpy (gs3, "a", 1); /* { dg-warning "output truncated before terminating nul copying 1 byte from a string of the same length" } */
50 strncpy (gs3, "a", 2);
51 strncpy (gs3, "a", 3);
52 strncpy (gs3, "ab", 3);
53 strncpy (gs3, "abc", 3); /* { dg-warning "output truncated before terminating nul copying 3 bytes from a string of the same length" } */
55 /* It might perhaps be helpful to diagnose certain truncation even
56 for non-strings. Then again, since the destination has been
57 explicitly annotated as non-string, it might be viewed as a false
58 positive. A valid use case seen in Glibc goes something like this:
60 #if FOO
61 # define S "1234"
62 #else
63 # define S "12345678"
64 #endif
66 strncpy (d, S, 8);
68 strncpy (gax_3, s7, 3);
70 strncpy (gax_1, "a", 1);
71 strncpy (gax_2, "ab", 2);
72 strncpy (gax_3, "abc", 3);
73 strncpy (gax_3, s7, 3);
75 strncpy (gax_1, s, 1);
76 strncpy (gax_2, s, 1);
77 strncpy (gax_3, s, 1);
79 strncpy (gax_1, s, n);
80 strncpy (gax_2, s, n);
81 strncpy (gax_3, s, n);
85 void test_pointer (const char *s, unsigned n)
87 const char s7[] = "1234567";
89 strncpy (pns_1, "a", 1);
90 strncpy (pns_2, "ab", 2);
91 strncpy (pns_3, "abc", 3);
92 strncpy (pns_3, s7, 3);
94 strncpy (pns_1, s, 1);
95 strncpy (pns_2, s, 1);
96 strncpy (pns_3, s, 1);
98 strncpy (pns_1, s, n);
99 strncpy (pns_2, s, n);
100 strncpy (pns_3, s, n);
104 void test_member_array (struct MemArrays *p, const char *s, unsigned n)
106 const char s7[] = "1234567";
108 strncpy (p->ma3, "", 0);
109 strncpy (p->ma3, "a", 1);
110 strncpy (p->ma4, "ab", 2);
111 strncpy (p->ma5, "abc", 3);
112 strncpy (p->max, "abcd", 4);
113 strncpy (p->max, s7, 5);
115 strncpy (p->ma3, s, 1);
116 strncpy (p->ma4, s, 1);
117 strncpy (p->ma5, s, 1);
118 strncpy (p->max, s, 1);
120 strncpy (p->ma3, s7, n);
121 strncpy (p->ma4, s7, n);
122 strncpy (p->ma5, s7, n);
123 strncpy (p->max, s7, n);