blob: 9273690fef320439fb13db71efc13abd1e7da45c [file] [log] [blame]
/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
{ dg-do compile }
{ dg-options "-O2 -Wall" }
{ dg-require-effective-target alloca } */
#define ATTR(...) __attribute__ ((__VA_ARGS__))
struct A { int a, b, c; };
struct B { int a, b, c[]; };
void sink (void*, ...);
ATTR (noipa) void*
return_alloca (int n)
{
void *p = __builtin_alloca (n);
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_index_cst (int n)
{
int *p = (int*)__builtin_alloca (n);
p = &p[1];
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_plus_cst (int n)
{
int *p = (int*)__builtin_alloca (n);
p += 1;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_plus_var (int n, int i)
{
char *p = (char*)__builtin_alloca (n);
p += i;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_member_1 (int n)
{
struct A *p = (struct A*)__builtin_alloca (n);
sink (&p->a);
return &p->a; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_member_2 (int n)
{
struct A *p = (struct A*)__builtin_alloca (n);
sink (&p->b);
return &p->b; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_flexarray (int n)
{
struct B *p = (struct B*)__builtin_alloca (n);
sink (p->c);
return p->c; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_array (void)
{
int a[32];
void *p = a;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_array_index_cst (void)
{
int a[32];
void *p = &a[2];
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_array_plus_cst (void)
{
int a[32];
void *p = a + 2;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_array_plus_var (int i)
{
int a[32];
void *p = a + i;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_array_member_1 (void)
{
struct A a[2];
int *p = &a[1].a;
sink (a, p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_array_member_2 (void)
{
struct A a[32];
int *p = &a[1].b;
sink (a, p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla (int n)
{
char a[n];
void *p = a;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla_index_cst (int n)
{
char a[n];
char *p = &a[3];
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla_plus_cst (int n)
{
char a[n];
char *p = a + 3;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla_index_var (int n, int i)
{
char a[n];
char *p = &a[i];
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla_plus_var (int n, int i)
{
char a[n];
char *p = a + i;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla_member_1 (int n, int i)
{
struct A a[n];
void *p = &a[i].a;
sink (a, p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_vla_member_2 (int n, int i)
{
struct A a[n];
void *p = &a[i].b;
sink (a, p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_or_alloca (int n, int i)
{
void *p = i ? __builtin_alloca (n * i) : __builtin_alloca (n);
sink (p);
/* The warning here should really be "function returns". */
return p; /* { dg-warning "function (returns|may return) address of local" } */
}
ATTR (noipa) void*
return_alloca_or_alloca_2 (int n, int i)
{
void *p0 = __builtin_alloca (n);
void *p1 = __builtin_alloca (n * 2);
void *p = i ? p0 : p1;
sink (p0, p1, p);
/* Same as above. */
return p; /* { dg-warning "function (returns|may return) address of local" } */
}
ATTR (noipa) void*
return_array_or_array (int i)
{
int a[5];
int b[7];
void *p = i ? a : b;
sink (a, b, p);
/* The warning here should really be "function returns". */
return p; /* { dg-warning "function (returns|may return) address of local" } */
}
ATTR (noipa) void*
return_array_or_array_plus_var (int i, int j)
{
int a[5];
int b[7];
void *p0 = a + i;
void *p1 = b + j;
void *p = i < j ? p0 : p1;
sink (a, b, p0, p1, p);
/* The warning here should really be "function returns". */
return p; /* { dg-warning "function (returns|may return) address of local" } */
}
extern int global[32];
ATTR (noipa) void*
may_return_global_or_alloca (int n, int i)
{
void *p = i ? global : __builtin_alloca (n);
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
may_return_global_or_alloca_plus_cst (int n, int i)
{
int *p = i ? global : (int*)__builtin_alloca (n);
p += 7;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
may_return_global_or_array (int n, int i)
{
int a[32];
void *p = i ? global : a;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
may_return_global_or_array_plus_cst (int n, int i)
{
int a[32];
int *p = i ? global : a;
p += 4;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
may_return_global_or_vla (int n, int i)
{
int a[n];
void *p = i ? global : a;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
may_return_global_or_vla_plus_cst (int n, int i)
{
int a[n];
int *p = i ? global : a;
p += 4;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}