1 /* { dg-do run } */
2 /* { dg-options "-O2" } */
3
4 /* PR target/20126 was not really target-specific, but rather a loop's
5 failure to take into account the possibility that a DEST_ADDR giv
6 replacement might fail, such as when you attempt to replace a REG
7 with a PLUS in one of the register_operands of cmpstrqi_rex_1. */
8
9 extern void abort (void);
10
11 typedef struct { int a; char b[3]; } S;
12 S c = { 2, "aa" }, d = { 2, "aa" };
13
14 void *
15 bar (const void *x, int y, int z)
16 {
17 return (void *) 0;
18 }
19
20 int
21 foo (S *x, S *y)
22 {
23 const char *e, *f, *g;
24 int h;
25
26 h = y->a;
27 f = y->b;
28 e = x->b;
29
30 if (h == 1)
31 return bar (e, *f, x->a) != 0;
32
33 g = e + x->a - h;
34 while (e <= g)
35 {
36 const char *t = e + 1;
37 /* The pointer E below increases but the bound H stays constant,
38 letting the latter exceed the size remaining in the argument
39 pointed to by the formed, which might be detected by
40 -Wstringop-overread. */
41 if (__builtin_memcmp (e, f, h) == 0)
42 return 1;
43 e = t;
44 }
45 return 0;
46 }
47
48 int
49 main (void)
50 {
51 if (foo (&c, &d) != 1)
52 abort ();
53 return 0;
54 }
55
56 /* { dg-prune-output "-Wstringop-overread" } */