1 /* { dg-do run } */
2 /* { dg-options "-fsanitize=bounds -Wall -Wextra -Wno-unused -Wno-array-bounds" } */
3
4 /* Test flexible array member-like arrays. Normal flexible array members
5 are tested in bounds-1.c. Test non-strict mode. */
6
7 __attribute__ ((noinline, noclone))
8 void
fn1(void)9 fn1 (void)
10 {
11 volatile struct S { char a[1]; char b; } s;
12 volatile int i;
13 asm ("" : : "r" (&s.a) : "memory");
14 i = s.a[0]; // OK
15 asm ("" : : "r" (&s.a) : "memory");
16 i = s.a[1]; // error
17 volatile struct S *p = &s;
18 asm ("" : : "r" (&p->a) : "memory");
19 i = p->a[0]; // OK
20 asm ("" : : "r" (&p->a) : "memory");
21 i = p->a[1]; // error
22 }
23
24 __attribute__ ((noinline, noclone))
25 void
fn2(void)26 fn2 (void)
27 {
28 struct S { int c; char d[4]; };
29 volatile struct T { int e; struct S f; int g; } t;
30 volatile int i;
31 asm ("" : : "r" (&t.f.d) : "memory");
32 i = t.f.d[3]; // OK
33 asm ("" : : "r" (&t.f.d) : "memory");
34 i = t.f.d[4]; // error
35 volatile struct T *p = &t;
36 asm ("" : : "r" (&p->f.d) : "memory");
37 i = p->f.d[3]; // OK
38 asm ("" : : "r" (&p->f.d) : "memory");
39 i = p->f.d[4]; // error
40 }
41
42 __attribute__ ((noinline, noclone))
43 void
fn3(void)44 fn3 (void)
45 {
46 volatile struct S { char b; char a[1]; } s;
47 volatile int i;
48 asm ("" : : "r" (&s.a) : "memory");
49 i = s.a[0]; // OK
50 asm ("" : : "r" (&s.a) : "memory");
51 i = s.a[1]; // error
52 volatile struct S *p = &s;
53 asm ("" : : "r" (&p->a) : "memory");
54 i = p->a[0]; // OK
55 asm ("" : : "r" (&p->a) : "memory");
56 i = p->a[1]; // error in strict mode
57 }
58
59 __attribute__ ((noinline, noclone))
60 void
fn4(void)61 fn4 (void)
62 {
63 volatile struct S { char b; char a[1]; } s;
64 volatile struct T { struct S s; int i; } t;
65 volatile int i;
66 asm ("" : : "r" (&t.s.a) : "memory");
67 i = t.s.a[0]; // OK
68 asm ("" : : "r" (&t.s.a) : "memory");
69 i = t.s.a[1]; // error
70 volatile struct T *pt = &t;
71 asm ("" : : "r" (&pt->s.a) : "memory");
72 i = pt->s.a[0]; // OK
73 asm ("" : : "r" (&pt->s.a) : "memory");
74 i = pt->s.a[1]; // error
75 }
76
77 __attribute__ ((noinline, noclone))
78 void
fn5(void)79 fn5 (void)
80 {
81 volatile struct S { char b; char a[1]; } s;
82 volatile struct U { int a; struct S s; } u;
83 volatile int i;
84 asm ("" : : "r" (&u.s.a) : "memory");
85 i = u.s.a[0]; // OK
86 asm ("" : : "r" (&u.s.a) : "memory");
87 i = u.s.a[1]; // error
88 volatile struct U *pu = &u;
89 asm ("" : : "r" (&pu->s.a) : "memory");
90 i = pu->s.a[0]; // OK
91 asm ("" : : "r" (&pu->s.a) : "memory");
92 i = pu->s.a[1]; // error in strict mode
93 }
94
95 int
main(void)96 main (void)
97 {
98 fn1 ();
99 fn2 ();
100 fn3 ();
101 fn4 ();
102 fn5 ();
103 return 0;
104 }
105
106 /* { dg-output "index 1 out of bounds for type 'char \\\[1\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
107 /* { dg-output "\[^\n\r]*index 1 out of bounds for type 'char \\\[1\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
108 /* { dg-output "\[^\n\r]*index 4 out of bounds for type 'char \\\[4\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
109 /* { dg-output "\[^\n\r]*index 4 out of bounds for type 'char \\\[4\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
110 /* { dg-output "\[^\n\r]*index 1 out of bounds for type 'char \\\[1\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
111 /* { dg-output "\[^\n\r]*index 1 out of bounds for type 'char \\\[1\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
112 /* { dg-output "\[^\n\r]*index 1 out of bounds for type 'char \\\[1\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
113 /* { dg-output "\[^\n\r]*index 1 out of bounds for type 'char \\\[1\\\]'" } */
114