1  // TODO: remove need for the taint option:
       2  /* { dg-additional-options "-fanalyzer-checker=taint" } */
       3  /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
       4  
       5  #define LOWER_LIMIT 5
       6  #define UPPER_LIMIT 20
       7  
       8  static int arr[UPPER_LIMIT];
       9  
      10  static int
      11  called_by_test_1 (int iarg)
      12  {
      13    return arr[iarg]; /* { dg-warning "without bounds checking" } */
      14  }
      15  
      16  int __attribute__((tainted_args))
      17  test_1 (unsigned long ularg)
      18  {
      19    return called_by_test_1 (ularg);
      20  }
      21  
      22  static int
      23  called_by_test_2 (int iarg)
      24  {
      25    if (iarg < LOWER_LIMIT || iarg > UPPER_LIMIT)
      26      return 0;
      27    return arr[iarg]; /* { dg-bogus "bounds checking" } */
      28  }
      29  
      30  int __attribute__((tainted_args))
      31  test_2 (unsigned long ularg)
      32  {
      33    return called_by_test_2 (ularg);
      34  }
      35  
      36  int __attribute__((tainted_args))
      37  test_3 (int iarg)
      38  {
      39    if (iarg < LOWER_LIMIT || iarg > UPPER_LIMIT)
      40      return 0;
      41    return arr[iarg]; /* { dg-bogus "bounds checking" } */
      42  }
      43  
      44  static int
      45  called_by_test_4 (int iarg)
      46  {
      47    if (iarg < LOWER_LIMIT || iarg > UPPER_LIMIT)
      48      return 0;
      49    return arr[iarg]; /* { dg-bogus "bounds checking" } */
      50  }
      51  
      52  int __attribute__((tainted_args))
      53  test_4 (unsigned uarg)
      54  {
      55    return called_by_test_4 (uarg);
      56  }
      57  
      58  int  __attribute__((tainted_args))
      59  test_5 (int idx)
      60  {
      61    switch (idx)
      62      {
      63      default:
      64        return 0;
      65      case 5 ... 20:
      66        return arr[idx]; /* { dg-bogus "bounds checking" } */
      67        /* 20 is still an out-of-bounds error (off-by-one)
      68  	 but we don't check for that, just that bounds have been imposed.  */
      69  
      70      /* Extra cases to avoid optimizing the switch away.  */
      71      case 22:
      72        return 22;
      73      case 23:
      74        return -17;
      75      }
      76  }
      77  
      78  int  __attribute__((tainted_args))
      79  test_6 (int idx)
      80  {
      81    switch (idx)
      82      {
      83      default:
      84        return arr[idx]; /* { dg-warning "without bounds checking" } */
      85  
      86      case 2:
      87        return arr[idx]; /* { dg-bogus "bounds checking" } */
      88  
      89      case 6 ... 19:
      90        return arr[idx]; /* { dg-bogus "bounds checking" } */
      91  
      92      case 22:
      93        return 22;
      94      case 23:
      95        return -17;
      96      }
      97  }
      98  
      99  int  __attribute__((tainted_args))
     100  test_7 (int idx)
     101  {
     102    switch (idx)
     103      {
     104      default:
     105        return arr[idx]; /* { dg-warning "without bounds checking" } */
     106  
     107      case 2 ... 4:
     108      case 7 ... 9:
     109        return arr[idx]; /* { dg-bogus "bounds checking" } */
     110  
     111      case 12 ... 19:
     112        return arr[idx]; /* { dg-bogus "bounds checking" } */
     113  
     114      case 22:
     115        return 22;
     116      case 23:
     117        return -17;
     118      }
     119  }
     120  
     121  int  __attribute__((tainted_args))
     122  test_8 (unsigned idx)
     123  {
     124    switch (idx)
     125      {
     126      default:
     127        return arr[idx]; /* { dg-warning "without upper-bounds checking" } */
     128  
     129      case 2 ... 4:
     130      case 7 ... 9:
     131        return arr[idx]; /* { dg-bogus "bounds checking" } */
     132  
     133      case 12 ... 19:
     134        return arr[idx]; /* { dg-bogus "bounds checking" } */
     135  
     136      case 22:
     137        return 22;
     138      case 23:
     139        return -17;
     140      }
     141  }