(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wrestrict-23.c
       1  /* PR tree-optimization/102238 - missing -Wrestrict on sprintf formatting
       2     a struct member into enclosing object
       3     { dg-do compile }
       4     { dg-options "-O2 -Wall -Wno-format-overflow" } */
       5  
       6  extern int sprintf (char*, const char*, ...);
       7  
       8  extern void sink (void*, ...);
       9  
      10  struct A
      11  {
      12    char a[4];
      13  };
      14  
      15  struct B
      16  {
      17    struct A a1, a2;
      18  };
      19  
      20  extern struct B eb;
      21  
      22  enum { B_a2_a_off = __builtin_offsetof (struct B, a2.a) };
      23  
      24  
      25  void test_warn_src_decl_plus (void)
      26  {
      27    {
      28      char *s = (char*)&eb + B_a2_a_off;
      29      char *d = eb.a2.a;
      30      sprintf (d, "%s", s);     // { dg-warning "overlaps" }
      31    }
      32  
      33    {
      34      // If strlen (s) > 0 there is overlap with a[1].
      35      char *s = (char*)&eb + B_a2_a_off + 1;
      36      char *d = eb.a2.a;
      37      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
      38    }
      39  
      40    {
      41      // strlen (s) must be at most 1 so there can be no overlap with a.
      42      char *s = (char*)&eb + B_a2_a_off + 2;
      43      char *d = eb.a2.a;
      44      sprintf (d, "%s", s);     // { dg-bogus "-Wrestrict" }
      45    }
      46  
      47    {
      48      // strlen (s) must be at most 0 so there can be no overlap with a.
      49      char *s = (char*)&eb + B_a2_a_off + 3;
      50      char *d = eb.a2.a;
      51      sprintf (d, "%s", s);     // { dg-bogus "-Wrestrict" }
      52    }
      53  }
      54  
      55  
      56  void test_warn_src_ptr_plus (struct B *p)
      57  {
      58    {
      59      char *s = (char*)p + B_a2_a_off;
      60      char *d = p->a2.a;
      61      sprintf (d, "%s", s);     // { dg-warning "overlaps" }
      62    }
      63  
      64    {
      65      // If strlen (s) > 0 there is overlap with a[1].
      66      char *s = (char*)p + B_a2_a_off + 1;
      67      char *d = p->a2.a;
      68      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
      69    }
      70  
      71    {
      72      // strlen (s) must be at most 1 so there can be no overlap with a.
      73      char *s = (char*)p + B_a2_a_off + 2;
      74      char *d = p->a2.a;
      75      sprintf (d, "%s", s);     // { dg-bogus "-Wrestrict" }
      76    }
      77  
      78    {
      79      // strlen (s) must be at most 0 so there can be no overlap with a.
      80      char *s = (char*)p + B_a2_a_off + 3;
      81      char *d = p->a2.a;
      82      sprintf (d, "%s", s);     // { dg-bogus "-Wrestrict" }
      83    }
      84  }
      85  
      86  
      87  void test_warn_dst_decl_plus (void)
      88  {
      89    {
      90      char *s = eb.a2.a;
      91      char *d = (char*)&eb + B_a2_a_off;
      92      sprintf (d, "%s", s);     // { dg-warning "overlaps" }
      93    }
      94  
      95    {
      96      // If strlen (a) > 0 there is overlap with a[1].
      97      char *s = eb.a2.a;
      98      char *d = (char*)&eb + B_a2_a_off + 1;
      99      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
     100    }
     101  
     102    {
     103      // If strlen (a) > 1 there is overlap with a[2].
     104      char *s = eb.a2.a;
     105      char *d = (char*)&eb + B_a2_a_off + 2;
     106      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
     107    }
     108  
     109    {
     110      // If strlen (a) > 2 there is overlap with a[3].
     111      char *s = eb.a2.a;
     112      char *d = (char*)&eb + B_a2_a_off + 3;
     113      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
     114    }
     115  }
     116  
     117  
     118  void test_warn_dst_ptr_plus (struct B *p)
     119  {
     120    {
     121      char *s = p->a2.a;
     122      char *d = (char*)p + B_a2_a_off;
     123      sprintf (d, "%s", s);     // { dg-warning "overlaps" }
     124    }
     125  
     126    {
     127      // If strlen (a) > 0 there is overlap with a[1].
     128      char *s = p->a2.a;
     129      char *d = (char*)p + B_a2_a_off + 1;
     130      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
     131    }
     132  
     133    {
     134      // If strlen (a) > 1 there is overlap with a[2].
     135      char *s = p->a2.a;
     136      char *d = (char*)p + B_a2_a_off + 2;
     137      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
     138    }
     139  
     140    {
     141      // If strlen (a) > 2 there is overlap with a[3].
     142      char *s = p->a2.a;
     143      char *d = (char*)p + B_a2_a_off + 3;
     144      sprintf (d, "%s", s);     // { dg-warning "may overlap" }
     145    }
     146  }