(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wreturn-local-addr-3.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  typedef __INTPTR_TYPE__ intptr_t;
       9  
      10  struct A { int a, b, c; };
      11  struct B { int a, b, c[]; };
      12  
      13  extern int g1[5], g2[5], g3[5], g4[5], g5[5];
      14  
      15  void sink (void*, ...);
      16  
      17  /* Verify that a pointer difference expression is handled correctly
      18     even when converted to a pointer.  */
      19  
      20  ATTR (noipa) void*
      21  return_local_diff_cst (void)
      22  {
      23    int a[5];
      24    void *p = (void*)(&a[4] - &a[1]);
      25    return p;
      26  }
      27  
      28  ATTR (noipa) void*
      29  return_local_diff_var (int i, int j)
      30  {
      31    int a[5];
      32    void *p = (void*)(&a[j] - &a[i]);
      33    return p;
      34  }
      35  
      36  ATTR (noipa) void*
      37  return_2_locals (int i)
      38  {
      39    int a[1];         /* { dg-message "declared here" } */
      40    int b[2];         /* { dg-message "declared here" } */
      41    void *p = i < 0 ? a : b;
      42    return p;         /* { dg-warning "function returns address of local" } */
      43  }
      44  
      45  /* Verify that returning the address of a local converted to intptr_t
      46     is not diagnosed (see bug 90737 for a case the front-end gets wrong).  */
      47  
      48  ATTR (noipa) intptr_t
      49  return_int_2_locals (int i)
      50  {
      51    int a[1];
      52    int b[2];
      53    void *p = i < 0 ? a : b;
      54    return (intptr_t)p;
      55  }
      56  
      57  /* Verify that a conditional expression with a pointer first operand
      58     is handled correctly.  */
      59  
      60  ATTR (noipa) void*
      61  return_2_locals_ptrcond (void *q)
      62  {
      63    int a[1];         /* { dg-message "declared here" } */
      64    int b[2];         /* { dg-message "declared here" } */
      65    void *p = q ? a : b;
      66    return p;         /* { dg-warning "function returns address of local" } */
      67  }
      68  
      69  /* Verify that a preincrement expression with a pointer operand is
      70     handled correctly.  */
      71  
      72  ATTR (noipa) void*
      73  return_2_locals_ptrinc (void *q)
      74  {
      75    int a[1];         /* { dg-message "declared here" } */
      76    int b[2];         /* { dg-message "declared here" } */
      77    int *p = q ? a : b;
      78    return ++p;       /* { dg-warning "function returns address of local" } */
      79  }
      80  
      81  ATTR (noipa) void*
      82  return_3_locals (int i)
      83  {
      84    int a[1];         /* { dg-message "declared here" } */
      85    int b[2];         /* { dg-message "declared here" } */
      86    int c[3];         /* { dg-message "declared here" } */
      87  
      88    void *p = i < 0 ? a : 0 < i ? c : b;
      89    return p;         /* { dg-warning "function returns address of local" } */
      90  }
      91  
      92  /* Verify that a conditional expression with a pointer first operand
      93     is handled correctly.  */
      94  
      95  ATTR (noipa) void*
      96  return_3_locals_ptrcond (void *p, void *q)
      97  {
      98    int a[1];         /* { dg-message "declared here" } */
      99    int b[2];         /* { dg-message "declared here" } */
     100    int c[3];         /* { dg-message "declared here" } */
     101  
     102    void *r = q ? r ? a : b : c;
     103    return r;         /* { dg-warning "function returns address of local" } */
     104  }
     105  
     106  ATTR (noipa) void*
     107  return_5_locals (int i)
     108  {
     109    int a[1];         /* { dg-message "declared here" } */
     110    int b[2];         /* { dg-message "declared here" } */
     111    int c[3];         /* { dg-message "declared here" } */
     112    int d[4];         /* { dg-message "declared here" } */
     113    int e[5];         /* { dg-message "declared here" } */
     114  
     115    void *p = i < -1 ? a : i < 0 ? b : 1 < i ? e : 0 < i ? d : c;
     116    return p;         /* { dg-warning "function returns address of local" } */
     117  }
     118  
     119  ATTR (noipa) void*
     120  return_1_global_4_locals (int i)
     121  {
     122    int a[1];         /* { dg-message "declared here" } */
     123    int b[2];         /* { dg-message "declared here" } */
     124    int c[3];         /* { dg-message "declared here" } */
     125    int d[4];         /* { dg-message "declared here" } */
     126  
     127    void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? d : c;
     128    return p;         /* { dg-warning "function may return address of local" } */
     129  }
     130  
     131  ATTR (noipa) void*
     132  return_2_globals_3_locals (int i)
     133  {
     134    int a[1];         /* { dg-message "declared here" } */
     135    int b[2];         /* { dg-message "declared here" } */
     136    int c[3];         /* { dg-message "declared here" } */
     137  
     138    void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : c;
     139    return p;         /* { dg-warning "function may return address of local" } */
     140  }
     141  
     142  ATTR (noipa) void*
     143  return_3_globals_2_locals (int i)
     144  {
     145    int a[1];         /* { dg-message "declared here" } */
     146    int b[2];         /* { dg-message "declared here" } */
     147  
     148    void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3;
     149    return p;         /* { dg-warning "function may return address of local" } */
     150  }
     151  
     152  ATTR (noipa) void*
     153  return_4_globals_1_local (int i)
     154  {
     155    int a[1];         /* { dg-message "declared here" } */
     156  
     157    void *p = i < -1 ? a : i < 0 ? g1 : 1 < i ? g2 : 0 < i ? g4 : g3;
     158    return p;         /* { dg-warning "function may return address of local" } */
     159  }
     160  
     161  ATTR (noipa) void*
     162  return_all_globals (int i)
     163  {
     164    void *p = i < -1 ? g1 : i < 0 ? g2 : 1 < i ? g3 : 0 < i ? g5 : g4;
     165    return p;
     166  }
     167  
     168  
     169  ATTR (noipa) void*
     170  return_2_alloca_local_cstoff (int n, int i)
     171  {
     172    int *a = __builtin_alloca (n);  /* { dg-message "declared here" } */
     173    int *b = __builtin_alloca (n);  /* { dg-message "declared here" } */
     174    int *p = i < 0 ? a : b;
     175    p += 1;
     176    sink (p);
     177    return p;         /* { dg-warning "function returns address of local" } */
     178  }
     179  
     180  ATTR (noipa) void*
     181  return_alloca_local_cstoff (int n, int i)
     182  {
     183    int *a = __builtin_alloca (n);  /* { dg-message "declared here" } */
     184    int b[2];                       /* { dg-message "declared here" } */
     185    int *p = i < 0 ? a : b;
     186    p += 1;
     187    sink (p);
     188    return p;         /* { dg-warning "function returns address of local" } */
     189  }
     190  
     191  ATTR (noipa) void*
     192  return_local_alloca_cstoff (int n, int i)
     193  {
     194    int a[2];                       /* { dg-message "declared here" } */
     195    int *b = __builtin_alloca (n);  /* { dg-message "declared here" } */
     196    int *p = i < 0 ? a : b;
     197    p += 1;
     198    sink (p);
     199    return p;         /* { dg-warning "function returns address of local" } */
     200  }
     201  
     202  ATTR (noipa) void*
     203  return_2_locals_cstoff (int i)
     204  {
     205    int a[1];         /* { dg-message "declared here" } */
     206    int b[2];         /* { dg-message "declared here" } */
     207    int *p = i < 0 ? a : b;
     208    p += 1;
     209    sink (p);
     210    return p;         /* { dg-warning "function returns address of local" } */
     211  }
     212  
     213  ATTR (noipa) void*
     214  return_2_globals_3_locals_cstoff (int i)
     215  {
     216    int a[1];         /* { dg-message "declared here" } */
     217    int b[2];         /* { dg-message "declared here" } */
     218    int c[3];         /* { dg-message "declared here" } */
     219  
     220    int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : c;
     221    p += 1;
     222    sink (p);
     223    return p;         /* { dg-warning "function may return address of local" } */
     224  }
     225  
     226  ATTR (noipa) void*
     227  return_3_globals_alloca_local_varoff (int n, int i, int j)
     228  {
     229    int *a = __builtin_alloca (n);  /* { dg-message "declared here" } */
     230    int b[2];                       /* { dg-message "declared here" } */
     231  
     232    int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3;
     233    p += j;
     234    sink (p);
     235    return p;         /* { dg-warning "function may return address of local" } */
     236  }
     237  
     238  ATTR (noipa) void*
     239  return_3_globals_2_locals_varoff (int i, int j)
     240  {
     241    int a[1];         /* { dg-message "declared here" } */
     242    int b[2];         /* { dg-message "declared here" } */
     243  
     244    int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3;
     245    p += j;
     246    sink (p);
     247    return p;         /* { dg-warning "function may return address of local" } */
     248  }
     249