(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wrestrict-26.c
       1  /* Verify that sprintf calls with arrays or struct of arrays don't
       2     cause -Wrestrict false positives.
       3     { dg-do compile }
       4     { dg-options "-O2 -Wall -Wrestrict -ftrack-macro-expansion=0" } */
       5  
       6  #define sprintf(d, f, ...) (sprintf (d, f, __VA_ARGS__), sink (d))
       7  
       8  extern void sink (void*, ...);
       9  extern int (sprintf) (char*, const char*, ...);
      10  
      11  extern char ca[][2][8];
      12  
      13  void test_array_of_arrays (void)
      14  {
      15    sprintf (ca[0][0], "%s", ca[0][0]);     // { dg-warning "-Wrestrict" }
      16    sprintf (ca[0][0], "%s", ca[0][1]);
      17    sprintf (ca[0][0], "%s", ca[1][0]);
      18    sprintf (ca[0][0], "%s", ca[1][1]);
      19  
      20    sprintf (ca[0][1], "%s", ca[0][0]);
      21    sprintf (ca[0][1], "%s", ca[0][1]);     // { dg-warning "-Wrestrict" }
      22    sprintf (ca[0][1], "%s", ca[1][0]);
      23    sprintf (ca[0][1], "%s", ca[1][1]);
      24  
      25    sprintf (ca[1][0], "%s", ca[0][0]);
      26    sprintf (ca[1][0], "%s", ca[0][1]);
      27    sprintf (ca[1][0], "%s", ca[1][0]);     // { dg-warning "-Wrestrict" }
      28    sprintf (ca[1][0], "%s", ca[1][1]);
      29  
      30    sprintf (ca[1][1], "%s", ca[0][0]);
      31    sprintf (ca[1][1], "%s", ca[0][1]);
      32    sprintf (ca[1][1], "%s", ca[1][0]);
      33    sprintf (ca[1][1], "%s", ca[1][1]);     // { dg-warning "-Wrestrict" }
      34  }
      35  
      36  
      37  struct A
      38  {
      39    char a[2][2][8];
      40    char b[2][2][8];
      41    char c[2][2][8];
      42  };
      43  
      44  extern struct A aa[][2];
      45  
      46  void test_array_of_structs (void)
      47  {
      48    // Verify that calls with the same elements of the same array trigger
      49    // warnings as expected.
      50    sprintf (aa[0][0].a[0][0], "%s", aa[0][0].a[0][0]);     // { dg-warning "-Wrestrict" }
      51    sprintf (aa[0][0].a[0][1], "%s", aa[0][0].a[0][1]);     // { dg-warning "-Wrestrict" }
      52    sprintf (aa[0][0].a[1][0], "%s", aa[0][0].a[1][0]);     // { dg-warning "-Wrestrict" }
      53    sprintf (aa[0][0].a[1][1], "%s", aa[0][0].a[1][1]);     // { dg-warning "-Wrestrict" }
      54    sprintf (aa[0][1].a[0][0], "%s", aa[0][1].a[0][0]);     // { dg-warning "-Wrestrict" }
      55    sprintf (aa[0][1].a[0][1], "%s", aa[0][1].a[0][1]);     // { dg-warning "-Wrestrict" }
      56    sprintf (aa[0][1].a[1][0], "%s", aa[0][1].a[1][0]);     // { dg-warning "-Wrestrict" }
      57    sprintf (aa[0][1].a[1][1], "%s", aa[0][1].a[1][1]);     // { dg-warning "-Wrestrict" }
      58    sprintf (aa[1][0].a[0][0], "%s", aa[1][0].a[0][0]);     // { dg-warning "-Wrestrict" }
      59    sprintf (aa[1][0].a[0][1], "%s", aa[1][0].a[0][1]);     // { dg-warning "-Wrestrict" }
      60    sprintf (aa[1][0].a[1][0], "%s", aa[1][0].a[1][0]);     // { dg-warning "-Wrestrict" }
      61    sprintf (aa[1][0].a[1][1], "%s", aa[1][0].a[1][1]);     // { dg-warning "-Wrestrict" }
      62    sprintf (aa[1][1].a[0][0], "%s", aa[1][1].a[0][0]);     // { dg-warning "-Wrestrict" }
      63    sprintf (aa[1][1].a[0][1], "%s", aa[1][1].a[0][1]);     // { dg-warning "-Wrestrict" }
      64    sprintf (aa[1][1].a[1][0], "%s", aa[1][1].a[1][0]);     // { dg-warning "-Wrestrict" }
      65    sprintf (aa[1][1].a[1][1], "%s", aa[1][1].a[1][1]);     // { dg-warning "-Wrestrict" }
      66  
      67  #define NOWARN()
      68  
      69    // Exhaustively verify that calls with different elements of the same
      70    // array don't cause false positives.
      71  #undef NOWARN
      72  #define NOWARN(D, S)				\
      73    sprintf (D[0][0], "%s", S[0][0]);		\
      74    sprintf (D[0][0], "%s", S[0][1]);		\
      75    sprintf (D[0][0], "%s", S[1][0]);		\
      76    sprintf (D[0][0], "%s", S[1][1]);		\
      77    sprintf (D[0][1], "%s", S[0][0]);		\
      78    sprintf (D[0][1], "%s", S[0][1]);		\
      79    sprintf (D[0][1], "%s", S[1][0]);		\
      80    sprintf (D[0][1], "%s", S[1][1]);		\
      81    sprintf (D[1][0], "%s", S[0][0]);		\
      82    sprintf (D[1][0], "%s", S[0][1]);		\
      83    sprintf (D[1][0], "%s", S[1][0]);		\
      84    sprintf (D[1][0], "%s", S[1][1]);		\
      85    sprintf (D[1][1], "%s", S[0][0]);		\
      86    sprintf (D[1][1], "%s", S[0][1]);		\
      87    sprintf (D[1][1], "%s", S[1][0]);		\
      88    sprintf (D[1][1], "%s", S[1][1])
      89  
      90    NOWARN (aa[0][0].a, aa[0][1].a);
      91    NOWARN (aa[0][0].a, aa[1][0].a);
      92    NOWARN (aa[0][0].a, aa[1][1].a);
      93  
      94    NOWARN (aa[0][1].a, aa[0][0].a);
      95    NOWARN (aa[0][1].a, aa[1][0].a);
      96    NOWARN (aa[0][1].a, aa[1][1].a);
      97  
      98    NOWARN (aa[1][0].a, aa[0][0].a);
      99    NOWARN (aa[1][0].a, aa[0][1].a);
     100    NOWARN (aa[1][0].a, aa[1][1].a);
     101  
     102  #define NOWARN_MEM(M1, M2)			\
     103    NOWARN (aa[0][0].M1, aa[0][0].M2);		\
     104    NOWARN (aa[0][0].M1, aa[0][1].M2);		\
     105    NOWARN (aa[0][0].M1, aa[1][0].M2);		\
     106    NOWARN (aa[0][0].M1, aa[1][1].M2)
     107  
     108    NOWARN_MEM (a, b);
     109    NOWARN_MEM (a, c);
     110    NOWARN_MEM (b, a);
     111    NOWARN_MEM (b, c);
     112    NOWARN_MEM (c, a);
     113    NOWARN_MEM (c, b);
     114  }