1  /* PR tree-optimization/86914 - wrong code with strlen() of poor-man's
       2     flexible array member plus offset
       3     { dg-do compile }
       4     { dg-options "-O2 -Wall -fdump-tree-optimized" } */
       5  
       6  #include "strlenopt.h"
       7  
       8  struct A0 { char i, a[0]; };
       9  struct A1 { char i, a[1]; };
      10  struct A9 { char i, a[9]; };
      11  struct Ax { char i, a[]; };
      12  
      13  extern int a[];
      14  
      15  extern struct A0 a0;
      16  extern struct A1 a1;
      17  extern struct A9 a9;
      18  extern struct Ax ax;
      19  
      20  void test_var_flexarray_cst_off (void)
      21  {
      22    /* Use arbitrary constants greater than 16 in case GCC ever starts
      23       unrolling strlen() calls with small array arguments.  */
      24    a[0] = 17 < strlen (a0.a + 1);        // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
      25    a[1] = 19 < strlen (a1.a + 1);        // { dg-warning "\\\[-Wstringop-overread" }
      26    a[2] = 23 < strlen (a9.a + 9);        // { dg-warning "\\\[-Wstringop-overread" }
      27    a[3] = 29 < strlen (ax.a + 3);
      28  }
      29  
      30  void test_ptr_flexarray_cst_off (struct A0 *p0, struct A1 *p1,
      31  				 struct A9 *p9, struct Ax *px)
      32  {
      33    a[0] = 17 < strlen (p0->a + 1);
      34    a[1] = 19 < strlen (p1->a + 1);
      35    a[2] = 23 < strlen (p9->a + 9);
      36    a[3] = 29 < strlen (px->a + 3);
      37  }
      38  
      39  void test_ptr_flexarray_var_off (struct A0 *p0, struct A1 *p1,
      40  				 struct A9 *p9, struct Ax *px,
      41  				 int i)
      42  {
      43    a[0] = 17 < strlen (p0->a + i);
      44    a[1] = 19 < strlen (p1->a + i);
      45    a[2] = 23 < strlen (p9->a + i);
      46    a[3] = 29 < strlen (px->a + i);
      47  }
      48  
      49  /* { dg-final { scan-tree-dump-times "strlen" 12 "optimized" } } */