(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wreturn-local-addr-2.c
       1  /* PR c/71924 - missing -Wreturn-local-addr returning alloca result
       2     { dg-do compile }
       3     { dg-options "-O2 -Wall" }
       4     { dg-require-effective-target alloca } */
       5  
       6  #define ATTR(...) __attribute__ ((__VA_ARGS__))
       7  
       8  struct A { int a, b, c; };
       9  struct B { int a, b, c[]; };
      10  
      11  void sink (void*, ...);
      12  
      13  ATTR (noipa) void*
      14  return_alloca (int n)
      15  {
      16    void *p = __builtin_alloca (n);
      17    sink (p);
      18    return p;         /* { dg-warning "function returns address of local" } */
      19  }
      20  
      21  ATTR (noipa) void*
      22  return_alloca_index_cst (int n)
      23  {
      24    int *p = (int*)__builtin_alloca (n);
      25    p = &p[1];
      26    sink (p);
      27    return p;         /* { dg-warning "function returns address of local" } */
      28  }
      29  
      30  ATTR (noipa) void*
      31  return_alloca_plus_cst (int n)
      32  {
      33    int *p = (int*)__builtin_alloca (n);
      34    p += 1;
      35    sink (p);
      36    return p;         /* { dg-warning "function returns address of local" } */
      37  }
      38  
      39  ATTR (noipa) void*
      40  return_alloca_plus_var (int n, int i)
      41  {
      42    char *p = (char*)__builtin_alloca (n);
      43    p += i;
      44    sink (p);
      45    return p;         /* { dg-warning "function returns address of local" } */
      46  }
      47  
      48  ATTR (noipa) void*
      49  return_alloca_member_1 (int n)
      50  {
      51    struct A *p = (struct A*)__builtin_alloca (n);
      52    sink (&p->a);
      53    return &p->a;     /* { dg-warning "function returns address of local" } */
      54  }
      55  
      56  ATTR (noipa) void*
      57  return_alloca_member_2 (int n)
      58  {
      59    struct A *p = (struct A*)__builtin_alloca (n);
      60    sink (&p->b);
      61    return &p->b;     /* { dg-warning "function returns address of local" } */
      62  }
      63  
      64  ATTR (noipa) void*
      65  return_alloca_flexarray (int n)
      66  {
      67    struct B *p = (struct B*)__builtin_alloca (n);
      68    sink (p->c);
      69    return p->c;      /* { dg-warning "function returns address of local" } */
      70  }
      71  
      72  
      73  ATTR (noipa) void*
      74  return_array (void)
      75  {
      76    int a[32];
      77    void *p = a;
      78    sink (p);
      79    return p;         /* { dg-warning "function returns address of local" } */
      80  }
      81  
      82  ATTR (noipa) void*
      83  return_array_index_cst (void)
      84  {
      85    int a[32];
      86    void *p = &a[2];
      87    sink (p);
      88    return p;         /* { dg-warning "function returns address of local" } */
      89  }
      90  
      91  ATTR (noipa) void*
      92  return_array_plus_cst (void)
      93  {
      94    int a[32];
      95    void *p = a + 2;
      96    sink (p);
      97    return p;         /* { dg-warning "function returns address of local" } */
      98  }
      99  
     100  ATTR (noipa) void*
     101  return_array_plus_var (int i)
     102  {
     103    int a[32];
     104    void *p = a + i;
     105    sink (p);
     106    return p;         /* { dg-warning "function returns address of local" } */
     107  }
     108  
     109  ATTR (noipa) void*
     110  return_array_member_1 (void)
     111  {
     112    struct A a[2];
     113    int *p = &a[1].a;
     114    sink (a, p);
     115    return p;         /* { dg-warning "function returns address of local" } */
     116  }
     117  
     118  ATTR (noipa) void*
     119  return_array_member_2 (void)
     120  {
     121    struct A a[32];
     122    int *p = &a[1].b;
     123    sink (a, p);
     124    return p;         /* { dg-warning "function returns address of local" } */
     125  }
     126  
     127  
     128  ATTR (noipa) void*
     129  return_vla (int n)
     130  {
     131    char a[n];
     132    void *p = a;
     133    sink (p);
     134    return p;   /* { dg-warning "function returns address of local" } */
     135  }
     136  
     137  ATTR (noipa) void*
     138  return_vla_index_cst (int n)
     139  {
     140    char a[n];
     141    char *p = &a[3];
     142    sink (p);
     143    return p;   /* { dg-warning "function returns address of local" } */
     144  }
     145  
     146  ATTR (noipa) void*
     147  return_vla_plus_cst (int n)
     148  {
     149    char a[n];
     150    char *p = a + 3;
     151    sink (p);
     152    return p;   /* { dg-warning "function returns address of local" } */
     153  }
     154  
     155  ATTR (noipa) void*
     156  return_vla_index_var (int n, int i)
     157  {
     158    char a[n];
     159    char *p = &a[i];
     160    sink (p);
     161    return p;   /* { dg-warning "function returns address of local" } */
     162  }
     163  
     164  ATTR (noipa) void*
     165  return_vla_plus_var (int n, int i)
     166  {
     167    char a[n];
     168    char *p = a + i;
     169    sink (p);
     170    return p;   /* { dg-warning "function returns address of local" } */
     171  }
     172  
     173  ATTR (noipa) void*
     174  return_vla_member_1 (int n, int i)
     175  {
     176    struct A a[n];
     177    void *p = &a[i].a;
     178    sink (a, p);
     179    return p;   /* { dg-warning "function returns address of local" } */
     180  }
     181  
     182  ATTR (noipa) void*
     183  return_vla_member_2 (int n, int i)
     184  {
     185    struct A a[n];
     186    void *p = &a[i].b;
     187    sink (a, p);
     188    return p;   /* { dg-warning "function returns address of local" } */
     189  }
     190  
     191  
     192  ATTR (noipa) void*
     193  return_alloca_or_alloca (int n, int i)
     194  {
     195    void *p = i ? __builtin_alloca (n * i) : __builtin_alloca (n);
     196    sink (p);
     197    /* The warning here should really be "function returns".  */
     198    return p;   /* { dg-warning "function (returns|may return) address of local" } */
     199  }
     200  
     201  ATTR (noipa) void*
     202  return_alloca_or_alloca_2 (int n, int i)
     203  {
     204    void *p0 = __builtin_alloca (n);
     205    void *p1 = __builtin_alloca (n * 2);
     206    void *p = i ? p0 : p1;
     207    sink (p0, p1, p);
     208    /* Same as above.  */
     209    return p;   /* { dg-warning "function (returns|may return) address of local" } */
     210  }
     211  
     212  ATTR (noipa) void*
     213  return_array_or_array (int i)
     214  {
     215    int a[5];
     216    int b[7];
     217    void *p = i ? a : b;
     218    sink (a, b, p);
     219    /* The warning here should really be "function returns".  */
     220    return p;   /* { dg-warning "function (returns|may return) address of local" } */
     221  }
     222  
     223  ATTR (noipa) void*
     224  return_array_or_array_plus_var (int i, int j)
     225  {
     226    int a[5];
     227    int b[7];
     228  
     229    void *p0 = a + i;
     230    void *p1 = b + j;
     231  
     232    void *p = i < j ? p0 : p1;
     233    sink (a, b, p0, p1, p);
     234    /* The warning here should really be "function returns".  */
     235    return p;   /* { dg-warning "function (returns|may return) address of local" } */
     236  }
     237  
     238  extern int global[32];
     239  
     240  ATTR (noipa) void*
     241  may_return_global_or_alloca (int n, int i)
     242  {
     243    void *p = i ? global : __builtin_alloca (n);
     244    sink (p);
     245    return p;   /* { dg-warning "function may return address of local" } */
     246  }
     247  
     248  
     249  ATTR (noipa) void*
     250  may_return_global_or_alloca_plus_cst (int n, int i)
     251  {
     252    int *p = i ? global : (int*)__builtin_alloca (n);
     253    p += 7;
     254    sink (p);
     255    return p;   /* { dg-warning "function may return address of local" } */
     256  }
     257  
     258  ATTR (noipa) void*
     259  may_return_global_or_array (int n, int i)
     260  {
     261    int a[32];
     262    void *p = i ? global : a;
     263    sink (p);
     264    return p;   /* { dg-warning "function may return address of local" } */
     265  }
     266  
     267  ATTR (noipa) void*
     268  may_return_global_or_array_plus_cst (int n, int i)
     269  {
     270    int a[32];
     271    int *p = i ? global : a;
     272    p += 4;
     273    sink (p);
     274    return p;   /* { dg-warning "function may return address of local" } */
     275  }
     276  
     277  ATTR (noipa) void*
     278  may_return_global_or_vla (int n, int i)
     279  {
     280    int a[n];
     281    void *p = i ? global : a;
     282    sink (p);
     283    return p;   /* { dg-warning "function may return address of local" } */
     284  }
     285  
     286  ATTR (noipa) void*
     287  may_return_global_or_vla_plus_cst (int n, int i)
     288  {
     289    int a[n];
     290    int *p = i ? global : a;
     291    p += 4;
     292    sink (p);
     293    return p;   /* { dg-warning "function may return address of local" } */
     294  }