1  /* Various examples of safe array access for which -Warray-bounds
       2     shouldn't issue a warning at any optimization level
       3     (PR tree-optimization/83510).  */
       4  
       5  /* { dg-options "-Warray-bounds" } */
       6  
       7  /*  This test is XFAILed because thread1 threads a switch statement
       8      such that the various cases have been split into different
       9      independent blocks.  One of these blocks exposes an arr[i_27]
      10      which is later propagated by VRP to be arr[10].  This is an
      11      invalid access, but the array bounds code doesn't know it is an
      12      unreachable path.
      13  
      14      However, it is not until dom2 that we "know" that the value of the
      15      switch index is such that the path to arr[10] is unreachable.  For
      16      that matter, it is not until dom3 that we remove the unreachable
      17      path.
      18  
      19  
      20      See:
      21      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83510
      22      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83312
      23  
      24      It's not until here that ranger "knows" that the path is
      25      unreachable:
      26  
      27      thread1
      28      vrp1		<-- array bounds checking
      29      dce2
      30      stdarg
      31      cdce
      32      cselim
      33      copyprop
      34      ifcombine
      35      mergephi3		<-- too late
      36  */
      37  
      38  extern int get_flag (void);
      39  
      40  unsigned int arr[10];
      41  
      42  struct xyz {
      43    unsigned int a0;
      44  };
      45  
      46  extern void wfm(struct xyz *, int, unsigned int);
      47  
      48  static unsigned int f(struct xyz * ctx, unsigned int number)
      49  {
      50    switch (number) {
      51    case 0x9:
      52      return ctx->a0;
      53    case 0xA: case 0xB:
      54    case 0xC: case 0xD: case 0xE: case 0xF:
      55    case 0x10: case 0x11: case 0x12: case 0x13:
      56      return arr[number - 0xa];
      57    }
      58    return 0;
      59  }
      60  
      61  int g(struct xyz * ctx) {
      62    int i;
      63  
      64    for (i = 0; i < 10; i++) {
      65      wfm(ctx, i, f(ctx, i));
      66    }
      67  
      68    return 0;
      69  }
      70  
      71  int g_signed(struct xyz * ctx) {
      72    int i;
      73  
      74    for (i = 0; i < 10; i++) {
      75      wfm(ctx, i, f(ctx, i));
      76    }
      77  
      78    return 0;
      79  }
      80  
      81  void test_2 (struct xyz * ctx)
      82  {
      83    int i;
      84  
      85    for (i = 0; i < 10; i++) {
      86      if (get_flag ())
      87        wfm(ctx, i, f(ctx, i));
      88    }
      89  }
      90  
      91  void test_3 (struct xyz * ctx)
      92  {
      93    unsigned int i;
      94    
      95    for (i = 0; i < 10; i++) {
      96      switch (i) {
      97      case 0x9:
      98        wfm(ctx, i, ctx->a0);
      99        break;
     100      case 0xA: case 0xB:
     101      case 0xC: case 0xD: case 0xE: case 0xF:
     102      case 0x10: case 0x11: case 0x12: case 0x13:
     103        if (get_flag ())
     104  	wfm(ctx, i, arr[i - 0xa]);
     105        break;
     106      }
     107    }
     108  }
     109  
     110  void test_3_signed (struct xyz * ctx)
     111  {
     112    int i;
     113    
     114    for (i = 0; i < 10; i++) {
     115      switch (i) {
     116      case 0x9:
     117        wfm(ctx, i, ctx->a0);
     118        break;
     119      case 0xA: case 0xB:
     120      case 0xC: case 0xD: case 0xE: case 0xF:
     121      case 0x10: case 0x11: case 0x12: case 0x13:
     122        if (get_flag ())
     123  	wfm(ctx, i, arr[i]);
     124        break;
     125      }
     126    }
     127  }
     128  
     129  void test_4 (struct xyz * ctx)
     130  {
     131    unsigned int i, j;
     132    
     133    for (i = 0; i < 10; i++) {
     134      switch (i) {
     135      case 0x9:
     136        wfm(ctx, i, ctx->a0);
     137        break;
     138      case 0xA: case 0xB:
     139      case 0xC: case 0xD: case 0xE: case 0xF:
     140      case 0x10: case 0x11: case 0x12: case 0x13:
     141        for (j = 0; j < 5; j++)
     142  	wfm(ctx, i, arr[i - 0xa]);
     143        break;
     144      }
     145    }
     146  }
     147  void test_4_signed (struct xyz * ctx)
     148  {
     149    int i, j;
     150    
     151    for (i = 0; i < 10; i++) {
     152      switch (i) {
     153      case 0x9:
     154        wfm(ctx, i, ctx->a0);
     155        break;
     156      case 0xA: case 0xB:
     157      case 0xC: case 0xD: case 0xE: case 0xF:
     158      case 0x10: case 0x11: case 0x12: case 0x13:
     159        for (j = 0; j < 5; j++)
     160  	wfm(ctx, i, arr[i]);
     161        break;
     162      }
     163    }
     164  }
     165  
     166  void test_5 (struct xyz * ctx)
     167  {
     168    unsigned int i;
     169    for (i = 10; i < 20; i++) {
     170      wfm(ctx, i, arr[i - 10]);
     171    }    
     172  }
     173  
     174  void test_5_signed (struct xyz * ctx)
     175  {
     176    int i;
     177    for (i = 10; i < 20; i++) {
     178      wfm(ctx, i, arr[i - 10]);
     179    }    
     180  }