1 /* Test to exercise attribute "nonstring".
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))
11 /* Global string with an unknown bound. */
14 /* Global string with an known bound. */
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. */
27 /* Global string pointer. */
30 /* Global non-string pointers. */
31 extern NONSTR
char *pns_1
;
32 extern char* NONSTR pns_2
;
33 extern char *pns_3 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:
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
);