]>
Commit | Line | Data |
---|---|---|
5acc654e MS |
1 | /* PR middle-end/95667 - unintended warning for memset writing across multiple |
2 | members | |
3 | { dg-do compile } | |
ebd20377 TV |
4 | { dg-options "-O2 -Wall" } |
5 | { dg-require-effective-target alloca } */ | |
5acc654e MS |
6 | |
7 | extern void sink (void*); | |
8 | ||
9 | struct S1 { char a[3], b[5]; }; | |
10 | ||
11 | void warn_strcpy_s1 (void) | |
12 | { | |
13 | struct S1 *p = __builtin_malloc (sizeof *p); | |
14 | char s[] = "1234567"; | |
15 | __builtin_strcpy (p->a, s); // { dg-warning "\\\[-Wstringop-overflow" } | |
16 | sink (p); | |
17 | } | |
18 | ||
19 | void nowarn_memset_s1 (void) | |
20 | { | |
21 | struct S1 *p = __builtin_malloc (sizeof *p); | |
22 | __builtin_memset (p->a, 0, 8); // { dg-bogus "\\\[-Wstringop-overflow" } | |
23 | sink (p); | |
24 | } | |
25 | ||
26 | struct S2 { char a[2], b[2][2], c[3]; }; | |
27 | ||
28 | void nowarn_memset_s2 (void) | |
29 | { | |
30 | struct S2 *p = __builtin_malloc (sizeof *p); | |
31 | ||
32 | __builtin_memset (p->a, 0, sizeof *p); | |
33 | sink (p); | |
34 | ||
35 | __builtin_memset (p->b, 0, 7); | |
36 | sink (p); | |
37 | ||
38 | __builtin_memset (&p->b[0], 0, 7); | |
39 | sink (p); | |
40 | ||
41 | __builtin_memset (&p->b[1], 0, 5); | |
42 | sink (p); | |
43 | ||
44 | __builtin_memset (&p->b[0][0], 0, 7); | |
45 | sink (p); | |
46 | ||
47 | __builtin_memset (&p->b[0][1], 0, 6); | |
48 | sink (p); | |
49 | ||
50 | __builtin_memset (&p->b[1][0], 0, 5); | |
51 | sink (p); | |
52 | ||
53 | __builtin_memset (&p->b[1][1], 0, 4); | |
54 | sink (p); | |
55 | } | |
56 | ||
57 | void warn_memset_s2 (void) | |
58 | { | |
59 | const unsigned n = sizeof (struct S2); | |
60 | struct S2 *p = __builtin_malloc (n); | |
61 | ||
62 | /* These should trigger -Wstringop-overflow rather than -Warray-bounds | |
63 | but the main purpose of the test is to verify the absence of warnings | |
64 | above so the exact warning for these overflwing calls isn't important | |
65 | here. */ | |
66 | ||
67 | __builtin_memset (p->a, 0, n + 1); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
68 | sink (p); | |
69 | ||
70 | __builtin_memset (p->b, 0, 8); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
71 | sink (p); | |
72 | ||
73 | __builtin_memset (&p->b[0], 0, 8); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
74 | sink (p); | |
75 | ||
76 | __builtin_memset (&p->b[0][0], 0, 8); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
77 | sink (p); | |
78 | ||
79 | __builtin_memset (&p->b[1], 0, 6); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
80 | sink (p); | |
81 | ||
82 | __builtin_memset (&p->b[0][1], 0, 7); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
83 | sink (p); | |
84 | } | |
85 | ||
86 | void nowarn_vl_struct (unsigned n) | |
87 | { | |
88 | if (n < 3 || 5 < n) | |
89 | n = 3; | |
90 | ||
91 | struct V { char a[3], b[n], c[7]; } v; | |
92 | ||
93 | __builtin_memset (v.a, 0, 15); | |
94 | sink (&v); | |
95 | ||
96 | __builtin_memset (v.b, 0, 12); | |
97 | sink (&v); | |
98 | ||
99 | __builtin_memset (v.c, 0, 7); | |
100 | sink (&v); | |
101 | ||
102 | __builtin_memset (v.a, 0, 16); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
103 | sink (&v); | |
104 | ||
105 | __builtin_memset (v.b, 0, 13); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } | |
106 | sink (&v); | |
107 | ||
108 | /* The &V.C argument is represented as a variable offset from | |
109 | the beginning of the allocated object and there's no good | |
110 | way to figure out from its variable offset that it's base | |
111 | is the C member: | |
112 | s.1_12 = __builtin_alloca_with_align (prephitmp_24, 8); | |
113 | _9 = s.1_12 + prephitmp_27; | |
114 | __builtin_memset (_9, 0, 2); | |
115 | */ | |
116 | ||
117 | __builtin_memset (v.c, 0, 8); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr?????" { xfail *-*-* } } | |
118 | sink (&v); | |
119 | } |