(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
builtin-object-size-16.c
       1  /* PR 71831 - __builtin_object_size poor results with no optimization
       2     Verify that even without optimization __builtin_object_size returns
       3     a meaningful result for a subset of simple expressins.  In cases
       4     where the result could not easily be made to match the one obtained
       5     with optimization the built-in was made to fail instead.  */
       6  /* { dg-do run } */
       7  /* { dg-options "-O0" } */
       8  
       9  static int nfails;
      10  
      11  #define TEST_FAILURE(line, obj, type, expect, result)		\
      12    __builtin_printf ("FAIL: line %i: __builtin_object_size("	\
      13  		    #obj ", %i) == %zu, got %zu\n",		\
      14  		    line, type, expect, result), ++nfails
      15  
      16  #define bos(obj, type) __builtin_object_size (obj, type)
      17  #define size(obj, n) ((size_t)n == X ? sizeof *obj : (size_t)n)
      18  
      19  #define test(expect, type, obj)						\
      20    do {									\
      21      if (bos (obj, type)	!= size (obj, expect))				\
      22        TEST_FAILURE (__LINE__, obj, type, size (obj, expect), bos (obj, type)); \
      23    } while (0)
      24  
      25  #define T(r0, r1, r2, r3, obj)			\
      26    do {						\
      27      test (r0, 0, obj);				\
      28      test (r1, 1, obj);				\
      29      test (r2, 2, obj);				\
      30      test (r3, 3, obj);				\
      31    } while (0)
      32  
      33  /* For convenience.  Substitute for 'sizeof object' in test cases where
      34     the size can vary from target to target.  */
      35  #define X  (size_t)0xdeadbeef
      36  
      37  /* __builtin_object_size checking results are inconsistent for equivalent
      38     expressions (see bug 71831).  To avoid having duplicate the inconsistency
      39     at -O0 the built-in simply fails.  The results hardcoded in this test
      40     are those obtained with optimization (for easy comparison) but without
      41     optimization the macros below turn them into expected failures .  */
      42  #if __OPTIMIZE__
      43  #  define F0(n)    n
      44  #  define F1(n)    n
      45  #  define F2(n)    n
      46  #  define F3(n)    n
      47  #else
      48  #  define F0(n)   -1
      49  #  define F1(n)   -1
      50  #  define F2(n)    0
      51  #  define F3(n)    0
      52  #endif
      53  
      54  typedef __SIZE_TYPE__ size_t;
      55  
      56  extern char ax[];
      57  #ifndef __builtin_object_size
      58  char ax2[];               /* { dg-warning "assumed to have one element" } */
      59  #endif
      60  
      61  extern char a0[0];
      62  static char a1[1];
      63  static char a2[2];
      64  static char a9[9];
      65  
      66  #if __SIZEOF_SHORT__ == 4
      67  extern short ia0[0];
      68  static short ia1[1];
      69  static short ia9[9];
      70  #elif __SIZEOF_INT__ == 4
      71  extern int ia0[0];
      72  static int ia1[1];
      73  static int ia9[9];
      74  #elif __SIZEOF_LONG__ == 4
      75  extern long ia0[0];
      76  static long ia1[1];
      77  static long ia9[9];
      78  #endif
      79  
      80  static char a2x2[2][2];
      81  static char a3x5[3][5];
      82  
      83  struct Sx { char n, a[]; } sx;
      84  struct S0 { char n, a[0]; } s0;
      85  struct S1 { char n, a[1]; } s1;
      86  struct S2 { char n, a[2]; } s2;
      87  struct S9 { char n, a[9]; } s9;
      88  
      89  struct S2x2 { char n, a[2][2]; } s2x2;
      90  struct S3x5 { char n, a[3][5]; } s3x5;
      91  
      92  static __attribute__ ((noclone, noinline)) void
      93  test_arrays ()
      94  {
      95    T (    -1,      -1,       0,       0,   ax);
      96  
      97    T (     0,       0,       0,       0,   a0);
      98    T (     1,       1,       1,       1,   ax2);
      99  
     100    T (     1,       1,       1,       1,   a1);
     101    T (     2,       2,       2,       2,   a2);
     102    T (     9,       9,       9,       9,   a9);
     103  
     104    T (     0,       0,       0,       0,   a0);
     105    T (     1,       1,       1,       1,   ax2);
     106  
     107    T (     0,       0,       0,       0,   ia0);
     108    T (     4,       4,       4,       4,   ia1);
     109    T (    36,      36,      36,      36,   ia9);
     110  
     111    /* Not all results for multidimensional arrays make sense (see
     112       bug 77293).  The expected results below simply reflect those
     113       obtained at -O2 (modulo the known limitations at -O1).  */
     114    T (     4,       4,       4,       4,   a2x2);
     115    T (     4,       4,       4,       4,   &a2x2[0]);
     116    T (     4,       2,       4,       2,   &a2x2[0][0]);
     117    T (     0,  F1  (0),      0,       0,   &a2x2 + 1);
     118    T (     2,  F1 ( 2),      2,  F3 ( 2),  &a2x2[0] + 1);
     119    T (     3,  F1 ( 1),      3,  F3 ( 3),  &a2x2[0][0] + 1);
     120  
     121    T (    15,      15,      15,      15,   a3x5);
     122    T (    15,       5,      15,       5,   &a3x5[0][0] + 0);
     123    T (    14,  F1 ( 4),     14,  F3 (14),  &a3x5[0][0] + 1);
     124  
     125    T (     1,       1,       1,       1,   a1 + 0);
     126    T (     0,  F1  (0),      0,       0,   a1 + 1);
     127    T (     0,  F1 ( 0),      0,       0,   &a1 + 1);
     128    /* In the following the offset is out of bounds which makes
     129       the expression undefined.  Still, verify that the returned
     130       size is zero (and not some large number).  */
     131    T (     0,  F1  (0),      0,       0,   a1 + 2);
     132  
     133    T (     2,       2,       2,       2,   a2 + 0);
     134    T (     1,  F1 ( 1),      1, F3 ( 1),   a2 + 1);
     135    T (     0,  F1 ( 0),      0,       0,   a2 + 2);
     136  }
     137  
     138  static __attribute__ ((noclone, noinline)) void
     139  test_structs (struct Sx *psx, struct S0 *ps0, struct S1 *ps1, struct S9 *ps9)
     140  {
     141    /* The expected size of a declared object with a flexible array member
     142       is sizeof sx in all __builtin_object_size types.  */
     143    T (     X,       X,       X,       X,   &sx);
     144  
     145    /* The expected size of an unknown object with a flexible array member
     146       is unknown in all __builtin_object_size types.  */
     147    T (    -1,      -1,       0,       0,   psx);
     148  
     149    /* The expected size of a flexible array member of a declared object
     150       is zero.  */
     151    T (     0,       0,       0,       0,   sx.a);
     152  
     153    /* The expected size of a flexible array member of an unknown object
     154       is unknown.  */
     155    T (    -1,      -1,       0,       0,   psx->a);
     156  
     157    /* The expected size of a declared object with a zero-length array member
     158       is sizeof sx in all __builtin_object_size types.  */
     159    T (     X,       X,       X,       X,   &s0);
     160  
     161    /* The expected size of an unknown object with a zero-length array member
     162       is unknown in all __builtin_object_size types.  */
     163    T (    -1,      -1,       0,       0,   ps0);
     164  
     165    /* The expected size of a zero-length array member of a declared object
     166       is zero.  */
     167    T (     0,       0,       0,       0,   s0.a);
     168  
     169    /* The expected size of a zero-length array member of an unknown object
     170       is unknown.  */
     171    T (    -1,      -1,       0,       0,   ps0->a);
     172  
     173    T (     X,       X,       X,       X,   &s1);
     174    T (     1,       1,       1,       1,   s1.a);
     175    T (     0,  F1 (0),       0,       0,   s1.a + 1);
     176  
     177    /* GCC treats arrays of all sizes that are the last member of a struct
     178       as flexible array members.  */
     179    T (    -1,      -1,       0,       0,   ps1);
     180    T (    -1,      -1,       0,       0,   ps1->a);
     181    T (    -1,      -1,       0,       0,   ps1->a + 1);
     182  
     183    T (     X,       X,       X,       X,   &s9);
     184    T (     9,       9,       9,       9,   s9.a);
     185    T (     9,       9,       9,       9,   s9.a + 0);
     186    T (     8,  F1 ( 8),      8, F3 (  8),  s9.a + 1);
     187    T (     7,  F1 ( 7),      7, F3 (  7),  s9.a + 2);
     188    T (     0,  F1 ( 0),      0, F3 (  0),  s9.a + 9);
     189  
     190    /* The following make little sense but see bug 77301.  */
     191    T (    -1,      -1,       0,       0,   ps9);
     192    T (    -1,      -1,       0,       0,   ps9->a);
     193    T (    -1,      -1,       0,       0,   ps9->a + 1);
     194  }
     195  
     196  int
     197  main()
     198  {
     199    test_arrays ();
     200  
     201    test_structs (&sx, &s0, &s1, &s9);
     202  
     203    if (nfails)
     204      __builtin_abort ();
     205  
     206    return 0;
     207  }