131
|
1 /* PR tree-optimization/84468 - Inconsistent -Wstringop-truncation warnings
|
|
2 with -O2
|
|
3 { dg-do compile }
|
|
4 { dg-options "-O2 -Wstringop-truncation -ftrack-macro-expansion=0 -g" } */
|
|
5
|
|
6 #define strncpy __builtin_strncpy
|
|
7
|
|
8 struct A
|
|
9 {
|
|
10 char a[4];
|
|
11 };
|
|
12
|
|
13 void no_pred_succ_lit (struct A *p)
|
|
14 {
|
|
15 /* The following is folded early on, before the strncpy statement
|
|
16 has a basic block. Verify that the case is handled gracefully
|
|
17 (i.e., there's no assumption that the statement does have
|
|
18 a basic block). */
|
|
19 strncpy (p->a, "1234", sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
|
|
20 }
|
|
21
|
|
22 /* Verify a strncpy call in a basic block with no predecessor or
|
|
23 successor. */
|
|
24 void no_pred_succ (struct A *p, const struct A *q)
|
|
25 {
|
|
26 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
|
|
27 }
|
|
28
|
|
29
|
|
30 /* Verify a strncpy call in a basic block with no successor. */
|
|
31 void no_succ (struct A *p, const struct A *q)
|
|
32 {
|
|
33 if (q->a)
|
|
34 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
|
|
35 }
|
|
36
|
|
37 /* Verify a strncpy call in a basic block with nul assignment in
|
|
38 a successor block. */
|
|
39 void succ (struct A *p, const struct A *q)
|
|
40 {
|
|
41 /* Verify that the assignment suppresses the warning for the conditional
|
|
42 strcnpy call. The conditional should be folded to true since the
|
|
43 address of an array can never be null (see bug 84470). */
|
|
44 if (q->a)
|
|
45 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
46
|
|
47 p->a[sizeof p->a - 1] = 0;
|
|
48 }
|
|
49
|
|
50
|
|
51 void succ_2 (struct A *p, const struct A *q, int i)
|
|
52 {
|
|
53 /* Same as above but with a conditional that cannot be eliminated. */
|
|
54 if (i < 0)
|
|
55 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
56
|
|
57 p->a[sizeof p->a - 1] = 0;
|
|
58 }
|
|
59
|
|
60
|
|
61 /* Verify a strncpy call in a basic block with nul assignment in
|
|
62 the next successor block. */
|
|
63 int next_succ (struct A *p, const struct A *q, int i, int j)
|
|
64 {
|
|
65 /* Same as above but with a nested conditionals with else clauses. */
|
|
66 if (i < 0)
|
|
67 {
|
|
68 if (j < 0)
|
|
69 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
70 }
|
|
71 else
|
|
72 __builtin_strcpy (p->a, q->a);
|
|
73
|
|
74 p->a[sizeof p->a - 1] = 0;
|
|
75 return 0;
|
|
76 }
|
|
77
|
|
78
|
|
79 int next_succ_1 (struct A *p, const struct A *q, int i, int j)
|
|
80 {
|
|
81 /* Same as above but with a nested conditionals with else clauses. */
|
|
82 if (i < 0)
|
|
83 {
|
|
84 if (j < 0)
|
|
85 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
86 else
|
|
87 strncpy (p->a, q->a, sizeof p->a - 2); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
88 }
|
|
89
|
|
90 p->a[sizeof p->a - 2] = 0;
|
|
91 return 1;
|
|
92 }
|
|
93
|
|
94
|
|
95 int next_succ_2 (struct A *p, const struct A *q, int i, int j)
|
|
96 {
|
|
97 /* Same as above but with a nested conditionals with else clauses. */
|
|
98 if (i < 0)
|
|
99 {
|
|
100 if (j < 0)
|
|
101 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
102 else
|
|
103 strncpy (p->a, q->a, sizeof p->a - 2); /* { dg-bogus "\\\[-Wstringop-truncation" } */
|
|
104 }
|
|
105 else
|
|
106 __builtin_strcpy (p->a, q->a);
|
|
107
|
|
108 p->a[sizeof p->a - 2] = 0;
|
|
109 return 2;
|
|
110 }
|
|
111
|
|
112
|
|
113 void cond_succ_warn (struct A *p, const struct A *q, int i)
|
|
114 {
|
|
115 /* Verify that a conditional assignment doesn't suppress the warning. */
|
|
116 strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
|
|
117
|
|
118 if (i < 0)
|
|
119 p->a[sizeof p->a - 1] = 0;
|
|
120 }
|
|
121
|
|
122 void cond_succ_nowarn (struct A *p, const struct A *q)
|
|
123 {
|
|
124 /* Verify that distinct but provably equivalent conditionals are
|
|
125 recognized and don't trigger the warning. */
|
|
126 if (p != q)
|
|
127 strncpy (p->a, q->a, sizeof p->a - 1);
|
|
128
|
|
129 if (p->a != q->a)
|
|
130 p->a[sizeof p->a - 1] = 0;
|
|
131 }
|