(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
builtin-object-size-4.c
       1  /* { dg-do run } */
       2  /* { dg-options "-O2 -Wno-stringop-overread" } */
       3  /* { dg-require-effective-target alloca } */
       4  
       5  #include "builtin-object-size-common.h"
       6  
       7  struct A
       8  {
       9    char a[10];
      10    int b;
      11    char c[10];
      12  } y, w[4];
      13  
      14  extern char exta[];
      15  extern char extb[30];
      16  extern struct A extc[];
      17  struct A zerol[0];
      18  
      19  void
      20  __attribute__ ((noinline))
      21  test1 (void *q, int x)
      22  {
      23    struct A a;
      24    void *p = &a.a[3], *r;
      25    char var[x + 10];
      26    struct A vara[x + 10];
      27    if (x < 0)
      28      r = &a.a[9];
      29    else
      30      r = &a.c[1];
      31    if (__builtin_object_size (p, 3) != sizeof (a.a) - 3)
      32      FAIL ();
      33    if (__builtin_object_size (&a.c[9], 3)
      34        != sizeof (a.c) - 9)
      35      FAIL ();
      36    if (__builtin_object_size (q, 3) != 0)
      37      FAIL ();
      38  #ifdef __builtin_object_size
      39    if (__builtin_object_size (r, 3)
      40        != (x < 0 ? sizeof (a.a) - 9 : sizeof (a.c) - 1))
      41  #else
      42    if (__builtin_object_size (r, 3) != sizeof (a.a) - 9)
      43  #endif
      44      FAIL ();
      45    if (x < 6)
      46      r = &w[2].a[1];
      47    else
      48      r = &a.a[6];
      49    if (__builtin_object_size (&y, 3) != sizeof (y))
      50      FAIL ();
      51    if (__builtin_object_size (w, 3) != sizeof (w))
      52      FAIL ();
      53    if (__builtin_object_size (&y.b, 3) != sizeof (a.b))
      54      FAIL ();
      55  #ifdef __builtin_object_size
      56    if (__builtin_object_size (r, 3)
      57        != (x < 6 ? sizeof (w[2].a) - 1 : sizeof (a.a) - 6))
      58  #else
      59    if (__builtin_object_size (r, 3) != sizeof (a.a) - 6)
      60  #endif
      61      FAIL ();
      62    if (x < 20)
      63      r = malloc (30);
      64    else
      65      r = calloc (2, 16);
      66  #ifdef __builtin_object_size
      67    if (__builtin_object_size (r, 3) != (x < 20 ? 30 : 2 * 16))
      68  #else
      69    if (__builtin_object_size (r, 3) != 30)
      70  #endif
      71      FAIL ();
      72    if (x < 20)
      73      r = malloc (30);
      74    else
      75      r = calloc (2, 14);
      76  #ifdef __builtin_object_size
      77    if (__builtin_object_size (r, 3) != (x < 20 ? 30 : 2 * 14))
      78  #else
      79    if (__builtin_object_size (r, 3) != 2 * 14)
      80  #endif
      81      FAIL ();
      82    if (x < 30)
      83      r = malloc (sizeof (a));
      84    else
      85      r = &a.a[3];
      86  #ifdef __builtin_object_size
      87    size_t objsz = x < 30 ? sizeof (a) : sizeof (a.a) - 3;
      88    if (__builtin_object_size (r, 3) != objsz)
      89  #else
      90    if (__builtin_object_size (r, 3) != sizeof (a.a) - 3)
      91  #endif
      92      FAIL ();
      93    r = memcpy (r, "a", 2);
      94  #ifdef __builtin_object_size
      95    if (__builtin_object_size (r, 3) != objsz)
      96  #else
      97    if (__builtin_object_size (r, 3) != sizeof (a.a) - 3)
      98  #endif
      99      FAIL ();
     100    r = memcpy (r + 2, "b", 2) + 2;
     101  #ifdef __builtin_object_size
     102    if (__builtin_object_size (r, 3) != objsz - 4)
     103  #else
     104    if (__builtin_object_size (r, 3) != sizeof (a.a) - 3 - 4)
     105  #endif
     106      FAIL ();
     107    r = &a.a[4];
     108    r = memset (r, 'a', 2);
     109    if (__builtin_object_size (r, 3) != sizeof (a.a) - 4)
     110      FAIL ();
     111    r = memset (r + 2, 'b', 2) + 2;
     112    if (__builtin_object_size (r, 3) != sizeof (a.a) - 8)
     113      FAIL ();
     114    r = &a.a[1];
     115    r = strcpy (r, "ab");
     116    if (__builtin_object_size (r, 3) != sizeof (a.a) - 1)
     117      FAIL ();
     118    r = strcpy (r + 2, "cd") + 2;
     119    if (__builtin_object_size (r, 3) != sizeof (a.a) - 5)
     120      FAIL ();
     121    if (__builtin_object_size (exta, 3) != 0)
     122      FAIL ();
     123    if (__builtin_object_size (exta + 10, 3) != 0)
     124      FAIL ();
     125    if (__builtin_object_size (&exta[5], 3) != 0)
     126      FAIL ();
     127    if (__builtin_object_size (extb, 3) != sizeof (extb))
     128      FAIL ();
     129    if (__builtin_object_size (extb + 10, 3) != sizeof (extb) - 10)
     130      FAIL ();
     131    if (__builtin_object_size (&extb[5], 3) != sizeof (extb) - 5)
     132      FAIL ();
     133    if (__builtin_object_size (extc, 3) != 0)
     134      FAIL ();
     135    if (__builtin_object_size (extc + 10, 3) != 0)
     136      FAIL ();
     137    if (__builtin_object_size (&extc[5], 3) != 0)
     138      FAIL ();
     139    if (__builtin_object_size (&extc->a, 3) != 0)
     140      FAIL ();
     141    if (__builtin_object_size (&(extc + 10)->b, 3) != 0)
     142      FAIL ();
     143    if (__builtin_object_size (&extc[5].c[3], 3) != 0)
     144      FAIL ();
     145  #ifdef __builtin_object_size
     146    if (__builtin_object_size (var, 3) != x + 10)
     147      FAIL ();
     148    if (__builtin_object_size (var + 10, 3) != x)
     149      FAIL ();
     150    if (__builtin_object_size (&var[5], 3) != x + 5)
     151      FAIL ();
     152    if (__builtin_object_size (vara, 3) != (x + 10) * sizeof (struct A))
     153      FAIL ();
     154    if (__builtin_object_size (vara + 10, 3) != x * sizeof (struct A))
     155      FAIL ();    
     156    if (__builtin_object_size (&vara[5], 3) != (x + 5) * sizeof (struct A))
     157      FAIL ();
     158  #else
     159    if (__builtin_object_size (var, 3) != 0)
     160      FAIL ();
     161    if (__builtin_object_size (var + 10, 3) != 0)
     162      FAIL ();
     163    if (__builtin_object_size (&var[5], 3) != 0)
     164      FAIL ();
     165    if (__builtin_object_size (vara, 3) != 0)
     166      FAIL ();
     167    if (__builtin_object_size (vara + 10, 3) != 0)
     168      FAIL ();    
     169    if (__builtin_object_size (&vara[5], 3) != 0)
     170      FAIL ();
     171  #endif
     172    if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
     173      FAIL ();
     174    if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
     175      FAIL ();
     176    if (__builtin_object_size (&vara[5].a[4], 3) != sizeof (vara[0].a) - 4)
     177      FAIL ();
     178    if (__builtin_object_size (&vara[5].b, 3) != sizeof (vara[0].b))
     179      FAIL ();
     180    if (__builtin_object_size (&vara[7].c[7], 3) != sizeof (vara[0].c) - 7)
     181      FAIL ();
     182    if (__builtin_object_size (zerol, 3) != 0)
     183      FAIL ();
     184    if (__builtin_object_size (&zerol, 3) != 0)
     185      FAIL ();
     186    if (__builtin_object_size (&zerol[0], 3) != 0)
     187      FAIL ();
     188    if (__builtin_object_size (zerol[0].a, 3) != 0)
     189      FAIL ();
     190    if (__builtin_object_size (&zerol[0].a[0], 3) != 0)
     191      FAIL ();
     192    if (__builtin_object_size (&zerol[0].b, 3) != 0)
     193      FAIL ();
     194    if (__builtin_object_size ("abcdefg", 3) != sizeof ("abcdefg"))
     195      FAIL ();
     196    if (__builtin_object_size ("abcd\0efg", 3) != sizeof ("abcd\0efg"))
     197      FAIL ();
     198    if (__builtin_object_size (&"abcd\0efg", 3) != sizeof ("abcd\0efg"))
     199      FAIL ();
     200    if (__builtin_object_size (&"abcd\0efg"[0], 3) != sizeof ("abcd\0efg"))
     201      FAIL ();
     202    if (__builtin_object_size (&"abcd\0efg"[4], 3) != sizeof ("abcd\0efg") - 4)
     203      FAIL ();
     204    if (__builtin_object_size ("abcd\0efg" + 5, 3) != sizeof ("abcd\0efg") - 5)
     205      FAIL ();
     206    if (__builtin_object_size (L"abcdefg", 3) != sizeof (L"abcdefg"))
     207      FAIL ();
     208    r = (char *) L"abcd\0efg";
     209    if (__builtin_object_size (r + 2, 3) != sizeof (L"abcd\0efg") - 2)
     210      FAIL ();
     211    /* Prevent DSE from removing calls that prevent bad combining of
     212       addresses and offsets.  */
     213    asm volatile ("" : : "g" (&a));
     214  }
     215  
     216  size_t l1 = 1;
     217  
     218  void
     219  __attribute__ ((noinline))
     220  test2 (void)
     221  {
     222    struct B { char buf1[10]; char buf2[10]; } a;
     223    char *r, buf3[20];
     224    int i;
     225  #ifdef __builtin_object_size
     226    size_t dyn_res = 0;
     227  #endif
     228  
     229    if (sizeof (a) != 20)
     230      return;
     231  
     232    r = buf3;
     233    for (i = 0; i < 4; ++i)
     234      {
     235        if (i == l1 - 1)
     236  	r = &a.buf1[1];
     237        else if (i == l1)
     238  	r = &a.buf2[7];
     239        else if (i == l1 + 1)
     240  	r = &buf3[5];
     241        else if (i == l1 + 2)
     242  	r = &a.buf1[9];
     243      }
     244    if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 9)
     245      FAIL ();
     246    r = &buf3[20];
     247    for (i = 0; i < 4; ++i)
     248      {
     249        if (i == l1 - 1)
     250  	r = &a.buf1[7];
     251        else if (i == l1)
     252  	r = &a.buf2[7];
     253        else if (i == l1 + 1)
     254  	r = &buf3[5];
     255        else if (i == l1 + 2)
     256  	r = &a.buf1[9];
     257      }
     258    if (__builtin_object_size (r, 3) != 0)
     259      FAIL ();
     260    r = &buf3[1];
     261    for (i = 0; i < 4; ++i)
     262      {
     263        if (i == l1 - 1)
     264  	r = &a.buf1[6];
     265        else if (i == l1)
     266  	r = &a.buf2[4];
     267        else if (i == l1 + 1)
     268  	r = &buf3[5];
     269        else if (i == l1 + 2)
     270  	r = &a.buf1[2];
     271      }
     272  #ifdef __builtin_object_size
     273    dyn_res = sizeof (buf3) - 1;
     274  
     275    for (i = 0; i < 4; ++i)
     276      {
     277        if (i == l1 - 1)
     278  	dyn_res = sizeof (a.buf1) - 6;
     279        else if (i == l1)
     280  	dyn_res = sizeof (a.buf2) - 4;
     281        else if (i == l1 + 1)
     282  	dyn_res = sizeof (buf3) - 5;
     283        else if (i == l1 + 2)
     284  	dyn_res = sizeof (a.buf1) - 2;
     285      }
     286    if (__builtin_object_size (r, 3) != dyn_res)
     287      FAIL ();
     288  #else
     289    if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 6)
     290      FAIL ();
     291  #endif
     292    r += 2;
     293  #ifdef __builtin_object_size
     294    if (__builtin_object_size (r, 3) != dyn_res - 2)
     295      FAIL ();
     296    if (__builtin_object_size (r + 1, 3) != dyn_res - 3)
     297      FAIL ();
     298  #else
     299    if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 6 - 2)
     300      FAIL ();
     301    if (__builtin_object_size (r + 1, 3) != sizeof (a.buf1) - 6 - 3)
     302      FAIL ();
     303  #endif
     304  }
     305  
     306  void
     307  __attribute__ ((noinline))
     308  test3 (void)
     309  {
     310    char buf4[10];
     311    struct B { struct A a[2]; struct A b; char c[4]; char d; double e;
     312  	     _Complex double f; } x;
     313    double y;
     314    _Complex double z;
     315    double *dp;
     316  
     317    if (__builtin_object_size (buf4, 3) != sizeof (buf4))
     318      FAIL ();
     319    if (__builtin_object_size (&buf4, 3) != sizeof (buf4))
     320      FAIL ();
     321    if (__builtin_object_size (&buf4[0], 3) != sizeof (buf4))
     322      FAIL ();
     323    if (__builtin_object_size (&buf4[1], 3) != sizeof (buf4) - 1)
     324      FAIL ();
     325    if (__builtin_object_size (&x, 3) != sizeof (x))
     326      FAIL ();
     327    if (__builtin_object_size (&x.a, 3) != sizeof (x.a))
     328      FAIL ();
     329    if (__builtin_object_size (&x.a[0], 3) != sizeof (x.a))
     330      FAIL ();
     331    if (__builtin_object_size (&x.a[0].a, 3) != sizeof (x.a[0].a))
     332      FAIL ();
     333    if (__builtin_object_size (&x.a[0].a[0], 3) != sizeof (x.a[0].a))
     334      FAIL ();
     335    if (__builtin_object_size (&x.a[0].a[3], 3) != sizeof (x.a[0].a) - 3)
     336      FAIL ();
     337    if (__builtin_object_size (&x.a[0].b, 3) != sizeof (x.a[0].b))
     338      FAIL ();
     339    if (__builtin_object_size (&x.a[1].c, 3) != sizeof (x.a[1].c))
     340      FAIL ();
     341    if (__builtin_object_size (&x.a[1].c[0], 3) != sizeof (x.a[1].c))
     342      FAIL ();
     343    if (__builtin_object_size (&x.a[1].c[3], 3) != sizeof (x.a[1].c) - 3)
     344      FAIL ();
     345    if (__builtin_object_size (&x.b, 3) != sizeof (x.b))
     346      FAIL ();
     347    if (__builtin_object_size (&x.b.a, 3) != sizeof (x.b.a))
     348      FAIL ();
     349    if (__builtin_object_size (&x.b.a[0], 3) != sizeof (x.b.a))
     350      FAIL ();
     351    if (__builtin_object_size (&x.b.a[3], 3) != sizeof (x.b.a) - 3)
     352      FAIL ();
     353    if (__builtin_object_size (&x.b.b, 3) != sizeof (x.b.b))
     354      FAIL ();
     355    if (__builtin_object_size (&x.b.c, 3) != sizeof (x.b.c))
     356      FAIL ();
     357    if (__builtin_object_size (&x.b.c[0], 3) != sizeof (x.b.c))
     358      FAIL ();
     359    if (__builtin_object_size (&x.b.c[3], 3) != sizeof (x.b.c) - 3)
     360      FAIL ();
     361    if (__builtin_object_size (&x.c, 3) != sizeof (x.c))
     362      FAIL ();
     363    if (__builtin_object_size (&x.c[0], 3) != sizeof (x.c))
     364      FAIL ();
     365    if (__builtin_object_size (&x.c[1], 3) != sizeof (x.c) - 1)
     366      FAIL ();
     367    if (__builtin_object_size (&x.d, 3) != sizeof (x.d))
     368      FAIL ();
     369    if (__builtin_object_size (&x.e, 3) != sizeof (x.e))
     370      FAIL ();
     371    if (__builtin_object_size (&x.f, 3) != sizeof (x.f))
     372      FAIL ();
     373    dp = &__real__ x.f;
     374    if (__builtin_object_size (dp, 3) != sizeof (x.f) / 2)
     375      FAIL ();
     376    dp = &__imag__ x.f;
     377    if (__builtin_object_size (dp, 3) != sizeof (x.f) / 2)
     378      FAIL ();
     379    dp = &y;
     380    if (__builtin_object_size (dp, 3) != sizeof (y))
     381      FAIL ();
     382    if (__builtin_object_size (&z, 3) != sizeof (z))
     383        FAIL ();
     384    dp = &__real__ z;
     385    if (__builtin_object_size (dp, 3) != sizeof (z) / 2)
     386      FAIL ();
     387    dp = &__imag__ z;
     388    if (__builtin_object_size (dp, 3) != sizeof (z) / 2)
     389      FAIL ();
     390  }
     391  
     392  struct S { unsigned int a; };
     393  
     394  char *
     395  __attribute__ ((noinline))
     396  test4 (char *x, int y)
     397  {
     398    register int i;
     399    struct A *p;
     400  
     401    for (i = 0; i < y; i++)
     402      {
     403        p = (struct A *) x;
     404        x = (char *) &p[1];
     405        if (__builtin_object_size (p, 3) != 0)
     406  	FAIL ();
     407      }
     408    return x;
     409  }
     410  
     411  void
     412  __attribute__ ((noinline))
     413  test5 (size_t x)
     414  {
     415    struct T { char buf[64]; char buf2[64]; } t;
     416    char *p = &t.buf[8];
     417    size_t i;
     418  
     419    for (i = 0; i < x; ++i)
     420      p = p + 4;
     421  #ifdef __builtin_object_size
     422    if (__builtin_object_size (p, 3) != sizeof (t.buf) - 8 - 4 * x)
     423  #else
     424    if (__builtin_object_size (p, 3) != 0)
     425  #endif
     426      FAIL ();
     427    memset (p, ' ', sizeof (t.buf) - 8 - 4 * 4);
     428  }
     429  
     430  void
     431  __attribute__ ((noinline))
     432  test6 (void)
     433  {
     434    char buf[64];
     435    struct T { char buf[64]; char buf2[64]; } t;
     436    char *p = &buf[64], *q = &t.buf[64];
     437  
     438    if (__builtin_object_size (p + 64, 3) != 0)
     439      FAIL ();
     440    if (__builtin_object_size (q + 0, 3) != 0)
     441      FAIL ();
     442    if (__builtin_object_size (q + 64, 3) != 0)
     443      FAIL ();
     444  }
     445  
     446  void
     447  __attribute__ ((noinline))
     448  test7 (void)
     449  {
     450    struct T { char buf[10]; char buf2[10]; } t;
     451    char *p = &t.buf2[-4];
     452    char *q = &t.buf2[0];
     453    if (__builtin_object_size (p, 3) != 0)
     454      FAIL ();
     455    if (__builtin_object_size (q, 3) != sizeof (t.buf2))
     456      FAIL ();
     457    q = &t.buf[10];
     458    if (__builtin_object_size (q, 3) != 0)
     459      FAIL ();
     460    q = &t.buf[11];
     461    if (__builtin_object_size (q, 3) != 0)
     462      FAIL ();
     463    p = &t.buf[-4];
     464    if (__builtin_object_size (p, 3) != 0)
     465      FAIL ();
     466  }
     467  
     468  void
     469  __attribute__ ((noinline))
     470  test8 (unsigned cond)
     471  {
     472    char *buf2 = malloc (10);
     473    char *p;
     474  
     475    if (cond)
     476      p = &buf2[8];
     477    else
     478      p = &buf2[4];
     479  
     480  #ifdef __builtin_object_size
     481    if (__builtin_object_size (&p[-4], 3) != (cond ? 6 : 10))
     482      FAIL ();
     483  #else
     484    if (__builtin_object_size (&p[-4], 3) != 0)
     485      FAIL ();
     486  #endif
     487  
     488    for (unsigned i = cond; i > 0; i--)
     489      p--;
     490  
     491  #ifdef __builtin_object_size
     492    if (__builtin_object_size (p, 3) != ((cond ? 2 : 6) + cond))
     493      FAIL ();
     494  #else
     495    if (__builtin_object_size (p, 3) != 0)
     496      FAIL ();
     497  #endif
     498  
     499    p = &y.c[8];
     500    for (unsigned i = cond; i > 0; i--)
     501      p--;
     502  
     503  #ifdef __builtin_object_size
     504    if (__builtin_object_size (p, 3) != sizeof (y.c) - 8 + cond)
     505      FAIL ();
     506  #else
     507    if (__builtin_object_size (p, 3) != 0)
     508      FAIL ();
     509  #endif
     510  }
     511  
     512  /* Tests for strdup/strndup.  */
     513  size_t
     514  __attribute__ ((noinline))
     515  test9 (void)
     516  {
     517    const char *ptr = "abcdefghijklmnopqrstuvwxyz";
     518    char *res = strndup (ptr, 21);
     519    if (__builtin_object_size (res, 3) != 22)
     520      FAIL ();
     521  
     522    free (res);
     523  
     524    res = strndup (ptr, 32);
     525    if (__builtin_object_size (res, 3) != 27)
     526      FAIL ();
     527  
     528    free (res);
     529  
     530    res = strdup (ptr);
     531    if (__builtin_object_size (res, 3) != 27)
     532      FAIL ();
     533  
     534    free (res);
     535  
     536    char *ptr2 = malloc (64);
     537    strcpy (ptr2, ptr);
     538  
     539    res = strndup (ptr2, 21);
     540    if (__builtin_object_size (res, 3) != 1)
     541      FAIL ();
     542  
     543    free (res);
     544  
     545    res = strndup (ptr2, 32);
     546    if (__builtin_object_size (res, 3) != 1)
     547      FAIL ();
     548  
     549    free (res);
     550  
     551    res = strndup (ptr2, 128);
     552    if (__builtin_object_size (res, 3) != 1)
     553      FAIL ();
     554  
     555    free (res);
     556  
     557    res = strdup (ptr2);
     558  #ifdef __builtin_object_size
     559    if (__builtin_object_size (res, 3) != 27)
     560  #else
     561    if (__builtin_object_size (res, 3) != 1)
     562  #endif
     563      FAIL ();
     564  
     565    free (res);
     566    free (ptr2);
     567  
     568    ptr = "abcd\0efghijklmnopqrstuvwxyz";
     569    res = strdup (ptr);
     570    if (__builtin_object_size (res, 3) != 5)
     571      FAIL ();
     572    free (res);
     573  
     574    res = strndup (ptr, 24);
     575    if (__builtin_object_size (res, 3) != 5)
     576      FAIL ();
     577    free (res);
     578  
     579    res = strndup (ptr, 2);
     580    if (__builtin_object_size (res, 3) != 3)
     581      FAIL ();
     582    free (res);
     583  
     584    res = strdup (&ptr[4]);
     585    if (__builtin_object_size (res, 3) != 1)
     586      FAIL ();
     587    free (res);
     588  
     589    res = strndup (&ptr[4], 4);
     590    if (__builtin_object_size (res, 3) != 1)
     591      FAIL ();
     592    free (res);
     593  
     594    res = strndup (&ptr[4], 1);
     595    if (__builtin_object_size (res, 3) != 1)
     596      FAIL ();
     597    free (res);
     598  }
     599  
     600  int
     601  main (void)
     602  {
     603    struct S s[10];
     604    __asm ("" : "=r" (l1) : "0" (l1));
     605    test1 (main, 6);
     606    test2 ();
     607    test3 ();
     608    test4 ((char *) s, 10);
     609    test5 (4);
     610    test6 ();
     611    test7 ();
     612    test8 (1);
     613    test9 ();
     614    DONE ();
     615  }