1 /* PR/tree-optimization/84480 - bogus -Wstringop-truncation despite
2    assignment with an inlined string literal
3    { dg-do compile }
4    { dg-options "-O2 -Wstringop-truncation" }  */
5 
6 #include <string.h>
7 
8 template <size_t N>
9 class GoodString
10 {
11 public:
12   GoodString (const char *s, size_t slen = N)
13   {
14     if (slen > N)
15       slen = N;
16 
17     strncpy (str, s, slen);
18 
19     str[slen] = '\0';
20   }
21 
22 private:
23   char str[N + 1];
24 };
25 
26 void sink (void*);
27 
good_nowarn_size_m2()28 void good_nowarn_size_m2 ()
29 {
30   GoodString<3> str ("12");
31   sink (&str);
32 }
33 
good_nowarn_size_m1()34 void good_nowarn_size_m1 ()
35 {
36   GoodString<3> str ("123");    // { dg-bogus "\\\[-Wstringop-truncation]" }
37   sink (&str);
38 }
39 
good_nowarn_size_m1_var(const char * s)40 static void good_nowarn_size_m1_var (const char* s)
41 {
42   GoodString<3> str (s);        // { dg-bogus "\\\[-Wstringop-truncation]" }
43   sink (&str);
44 }
45 
call_good_nowarn_size_m1_var()46 void call_good_nowarn_size_m1_var ()
47 {
48   good_nowarn_size_m1_var ("456");
49 }
50 
51 
52 template <size_t N>
53 class BadString1
54 {
55 public:
56   BadString1 (const char *s, size_t slen = N)
57   {
58     if (slen > N)
59       slen = N;
60 
61     strncpy (str, s, slen);
62   }
63 
64 private:
65   char str[N + 1];
66 };
67 
bad1_nowarn_size_m2()68 void bad1_nowarn_size_m2 ()
69 {
70   BadString1<3> str ("12");
71   sink (&str);
72 }
73 
74 
75 template <size_t N>
76 class BadString2
77 {
78 public:
79   BadString2 (const char *s, size_t slen = N)
80   {
81     if (slen > N)
82       slen = N;
83 
84     strncpy (str, s, slen);     // { dg-warning "\\\[-Wstringop-truncation]" }
85   }
86 
87 private:
88   char str[N + 1];
89 };
90 
bad2_warn_size_m1()91 void bad2_warn_size_m1 ()
92 {
93   BadString2<3> str ("123");
94   sink (&str);
95 }
96 
97 // { dg-message "inlined from .void bad2_warn_size_m1." "" { target *-*-* } 0 }
98 
99 template <size_t N>
100 class BadString3
101 {
102 public:
103   BadString3 (const char *s, size_t slen = N)
104   {
105     if (slen > N)
106       slen = N;
107 
108     strncpy (str, s, slen);     // { dg-warning "\\\[-Wstringop-truncation]" }
109   }
110 
111 private:
112   char str[N + 1];
113 };
114 
bad3_warn_size_m1_var(const char * s)115 static void bad3_warn_size_m1_var (const char *s)
116 {
117   BadString3<3> str (s);
118   sink (&str);
119 }
120 
call_bad3_warn_size_m1_var()121 void call_bad3_warn_size_m1_var ()
122 {
123   bad3_warn_size_m1_var ("456");
124 }
125 
126 // { dg-message "inlined from .void call_bad3_warn_size_m1_var." "" { target *-*-* } 0 }
127