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)) 8void 9fn1 (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)) 25void 26fn2 (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)) 43void 44fn3 (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)) 60void 61fn4 (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)) 78void 79fn5 (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 95int 96main (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