1  /* { dg-do run } */
       2  /* { dg-options "-fsanitize=bounds -Wall -Wextra -Wno-unused -Wno-array-bounds -Wno-uninitialized" } */
       3  /* { dg-options "-fsanitize=bounds -Wall -Wextra -Wno-unused -Wno-array-bounds -Wno-uninitialized -Wno-volatile" { target c++ } } */
       4  
       5  /* Test runtime errors.  */
       6  
       7  struct S { int a[10]; };
       8  struct T { int a[5]; int s[2]; };
       9  
      10  int
      11  foo_5 (void)
      12  {
      13    return 5;
      14  }
      15  
      16  __attribute__ ((noinline, noclone))
      17  void
      18  fn_p (int p)
      19  {
      20    (void) p;
      21  }
      22  
      23  static void __attribute__ ((noinline, noclone))
      24  fn1 (void)
      25  {
      26    volatile int a[5];
      27    asm ("" : : "r" (&a) : "memory");
      28    a[2] = a[5];
      29  }
      30  
      31  static void __attribute__ ((noinline, noclone))
      32  fn2 (void)
      33  {
      34    volatile int a[5];
      35    volatile int j;
      36    int i = 5;
      37    int *p = &i;
      38    asm ("" : : "r" (&a) : "memory");
      39    j = a[*p];
      40  }
      41  
      42  static void __attribute__ ((noinline, noclone))
      43  fn3 (void)
      44  {
      45    volatile int a[5];
      46    fn_p (a[5]);
      47  }
      48  
      49  static void __attribute__ ((noinline, noclone))
      50  fn4 (void)
      51  {
      52    struct T t;
      53    asm ("" : : "r" (&t.a) : "memory");
      54    t.a[foo_5 ()] = 1;
      55  }
      56  
      57  static void __attribute__ ((noinline, noclone))
      58  fn5 (void)
      59  {
      60    int i = 5;
      61    volatile int a[i];
      62    asm ("" : : "r" (&a) : "memory");
      63    a[2] = a[i];
      64  }
      65  
      66  static void __attribute__ ((noinline, noclone))
      67  fn6 (void)
      68  {
      69    int i = 5;
      70    volatile int a[i];
      71    volatile int j;
      72    fn_p (a[i]);
      73    asm ("" : : "r" (&a) : "memory");
      74    j = a[foo_5 ()];
      75  }
      76  
      77  static void __attribute__ ((noinline, noclone))
      78  fn7 (void)
      79  {
      80    int n = 5;
      81    volatile int i;
      82    volatile int c[n][n][n];
      83    asm ("" : : "r" (&c[5]) : "memory");
      84    i = c[5][2][2];
      85    asm ("" : : "r" (&c[2]) : "memory");
      86    i = c[2][5][2];
      87    asm ("" : : "r" (&c[2]) : "memory");
      88    i = c[2][2][5];
      89  }
      90  
      91  static void __attribute__ ((noinline, noclone))
      92  fn8 (void)
      93  {
      94    volatile int i;
      95    volatile struct S s;
      96    asm ("" : : "r" (&s.a) : "memory");
      97    i = s.a[10];
      98  }
      99  
     100  static void __attribute__ ((noinline, noclone))
     101  fn9 (void)
     102  {
     103    long int *volatile d[10][5];
     104    asm ("" : : "r" (&d[10]) : "memory");
     105    d[8][3] = d[10][0];
     106  }
     107  
     108  static void __attribute__ ((noinline, noclone))
     109  fn10 (void)
     110  {
     111    /* Beware of side-effects.  */
     112    volatile int x = 10;
     113    volatile int e[20];
     114    e[x++] = 3;
     115    if (x != 11)
     116      __builtin_abort ();
     117    e[x--] = 3;
     118    if (x != 10)
     119      __builtin_abort ();
     120  }
     121  
     122  static void __attribute__ ((noinline, noclone))
     123  fn11 (void)
     124  {
     125    char ***volatile f[5];
     126    asm ("" : : "r" (&f) : "memory");
     127    f[2] = f[5];
     128  }
     129  
     130  static void __attribute__ ((noinline, noclone))
     131  fn12 (int i)
     132  {
     133    volatile int a[5] = { };
     134    int k = i ? a[i] : i;
     135  }
     136  
     137  int
     138  main (void)
     139  {
     140    fn1 ();
     141    fn2 ();
     142    fn3 ();
     143    fn4 ();
     144    fn5 ();
     145    fn6 ();
     146    fn7 ();
     147    fn8 ();
     148    fn9 ();
     149    fn10 ();
     150    fn11 ();
     151    fn12 (5);
     152    return 0;
     153  }
     154  
     155  /* { dg-output "index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     156  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     157  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     158  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     159  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     160  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     161  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     162  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     163  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     164  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     165  /* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[10\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     166  /* { dg-output "\[^\n\r]*index 10 out of bounds for type 'long int \\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     167  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'char \\\*\\\*\\\*\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
     168  /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'" } */