131
|
1 /* PR tree-optimization/84095 - false-positive -Wrestrict warnings for
|
|
2 memcpy within array
|
|
3 { dg-do compile }
|
|
4 { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */
|
|
5
|
|
6 typedef __SIZE_TYPE__ size_t;
|
|
7
|
|
8 extern void* memcpy (void* restrict, const void* restrict, size_t);
|
|
9
|
|
10 #define T(d, s, n) memcpy (d, s, n)
|
|
11
|
|
12 struct S1 { char c; } a8_1[8];
|
|
13
|
|
14 void test_1_dim_var (int i, int j)
|
|
15 {
|
|
16 /* Variable destination index and constant source index. */
|
|
17 T (&a8_1[i], &a8_1[0], 1);
|
|
18 T (&a8_1[i], &a8_1[0], 2);
|
|
19 T (&a8_1[i], &a8_1[0], 3);
|
|
20 T (&a8_1[i], &a8_1[0], 4);
|
|
21
|
|
22 T (&a8_1[i], &a8_1[0], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and 0 overlaps between 2 and 5 bytes at offset \\\[0, 3\\\]" } */
|
|
23 T (&a8_1[i], &a8_1[0], 6); /* { dg-warning "accessing 6 bytes at offsets \\\[0, 8] and 0 overlaps between 4 and 6 bytes at offset \\\[0, 2\\\]" } */
|
|
24 T (&a8_1[i], &a8_1[0], 7); /* { dg-warning "accessing 7 bytes at offsets \\\[0, 8] and 0 overlaps between 6 and 7 bytes at offset \\\[0, 1\\\]" } */
|
|
25 T (&a8_1[i], &a8_1[0], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and 0 overlaps 8 bytes at offset 0" } */
|
|
26
|
|
27 /* The following is diagnosed by -Warray-bounds when it's enabled
|
|
28 rather than by -Wrestrict. */
|
|
29 T (&a8_1[i], &a8_1[0], 9); /* { dg-warning "accessing 9 bytes at offsets \\\[0, 8] and 0 overlaps 9 bytes at offset 0" } */
|
|
30
|
|
31 /* Same as above but with constant destination index and variable
|
|
32 source index. */
|
|
33 T (&a8_1[0], &a8_1[i], 1);
|
|
34 T (&a8_1[0], &a8_1[i], 2);
|
|
35 T (&a8_1[0], &a8_1[i], 3);
|
|
36 T (&a8_1[0], &a8_1[i], 4);
|
|
37
|
|
38 T (&a8_1[0], &a8_1[i], 5); /* { dg-warning "accessing 5 bytes at offsets 0 and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3\\\]" } */
|
|
39 T (&a8_1[0], &a8_1[i], 6); /* { dg-warning "accessing 6 bytes at offsets 0 and \\\[0, 8] overlaps between 4 and 6 bytes at offset \\\[0, 2\\\]" } */
|
|
40 T (&a8_1[0], &a8_1[i], 7); /* { dg-warning "accessing 7 bytes at offsets 0 and \\\[0, 8] overlaps between 6 and 7 bytes at offset \\\[0, 1\\\]" } */
|
|
41 T (&a8_1[0], &a8_1[i], 8); /* { dg-warning "accessing 8 bytes at offsets 0 and \\\[0, 8] overlaps 8 bytes at offset 0" } */
|
|
42 T (&a8_1[0], &a8_1[i], 9); /* { dg-warning "accessing 9 bytes at offsets 0 and \\\[0, 8] overlaps 9 bytes at offset 0" } */
|
|
43
|
|
44
|
|
45 /* Variable destination and source indices. */
|
|
46 T (&a8_1[i], &a8_1[j], 1);
|
|
47 T (&a8_1[i], &a8_1[j], 2);
|
|
48 T (&a8_1[i], &a8_1[j], 3);
|
|
49 T (&a8_1[i], &a8_1[j], 4);
|
|
50
|
|
51 T (&a8_1[i], &a8_1[j], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3\\\]" } */
|
|
52 T (&a8_1[i], &a8_1[j], 6); /* { dg-warning "accessing 6 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 4 and 6 bytes at offset \\\[0, 2\\\]" } */
|
|
53 T (&a8_1[i], &a8_1[j], 7); /* { dg-warning "accessing 7 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 6 and 7 bytes at offset \\\[0, 1\\\]" } */
|
|
54 T (&a8_1[i], &a8_1[j], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 8 bytes at offset 0" } */
|
|
55
|
|
56 /* The following is diagnosed by -Warray-bounds when it's enabled
|
|
57 rather than by -Wrestrict. */
|
|
58 T (&a8_1[i], &a8_1[j], 9); /* { dg-warning "accessing 9 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 9 bytes at offset 0" } */
|
|
59 }
|
|
60
|
|
61 struct S4 { char a4[4]; } a2_4[2];
|
|
62
|
|
63 void test_2_dim (int i, int j)
|
|
64 {
|
|
65 T (&a2_4[i], &a2_4[0], 1);
|
|
66 T (&a2_4[i], &a2_4[0], 4);
|
|
67
|
|
68 T (&a2_4[i], &a2_4[0], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and 0 overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
|
|
69 T (&a2_4[i], &a2_4[0], 6); /* { dg-warning "accessing 6 bytes at offsets \\\[0, 8] and 0 overlaps between 4 and 6 bytes at offset \\\[0, 2]" } */
|
|
70 T (&a2_4[i], &a2_4[0], 7); /* { dg-warning "accessing 7 bytes at offsets \\\[0, 8] and 0 overlaps between 6 and 7 bytes at offset \\\[0, 1]" } */
|
|
71 T (&a2_4[i], &a2_4[0], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and 0 overlaps 8 bytes at offset 0" } */
|
|
72
|
|
73 T (a2_4[i].a4, a2_4[0].a4, 1);
|
|
74 T (a2_4[i].a4, a2_4[0].a4, 4);
|
|
75
|
|
76 T (a2_4[i].a4, a2_4[0].a4, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and 0 overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
|
|
77 T (a2_4[i].a4, a2_4[0].a4, 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and 0 overlaps 8 bytes at offset 0" } */
|
|
78
|
|
79 T (a2_4[i].a4, a2_4[j].a4, 1);
|
|
80 T (a2_4[i].a4, a2_4[j].a4, 4);
|
|
81
|
|
82 /* The destination and source offsets printed below ignore the size
|
|
83 of the copy and only indicate the values that are valid for each
|
|
84 of the destination and source arguments on its own, without
|
|
85 considering the size of the overlapping access. */
|
|
86 T (a2_4[i].a4, a2_4[j].a4, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
|
|
87 T (a2_4[i].a4, a2_4[j].a4, 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 8 bytes at offset 0" } */
|
|
88
|
|
89 /* Same as above but referencing the first elements of each array. */
|
|
90 T (&a2_4[i].a4[0], &a2_4[j].a4[0], 1);
|
|
91 T (&a2_4[i].a4[0], &a2_4[j].a4[0], 4);
|
|
92
|
|
93 T (&a2_4[i].a4[0], &a2_4[j].a4[0], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
|
|
94 T (&a2_4[i].a4[0], &a2_4[j].a4[0], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 8 bytes at offset 0" } */
|
|
95
|
|
96 T (&a2_4[i].a4[0], &a2_4[j].a4[1], 3);
|
|
97 T (&a2_4[i].a4[0], &a2_4[j].a4[2], 2);
|
|
98 T (&a2_4[i].a4[0], &a2_4[j].a4[3], 1);
|
|
99 }
|
|
100
|
|
101 struct { int i; } a2[2][8];
|
|
102
|
|
103 void test_single_2_dim_major (int i)
|
|
104 {
|
|
105 memcpy (&a2[i], &a2[0], sizeof *a2); /* { dg-bogus "\\\[-Wrestrict]" } */
|
|
106 }
|
|
107
|
|
108 void test_single_2_dim_minor (int i)
|
|
109 {
|
|
110 memcpy (&a2[i][0], &a2[0][0], sizeof a2[0][0]); /* { dg-bogus "\\\[-Wrestrict]" } */
|
|
111 }
|
|
112
|
|
113 void test_single_2_dim_major_minor (int i, int j)
|
|
114 {
|
|
115 memcpy (&a2[i][j], &a2[0][0], sizeof a2[0][0]); /* { dg-bogus "\\\[-Wrestrict]" } */
|
|
116 }
|