blob: 4a3b07ba02cd4b4f9e7888cc8d8dedd55a5bf1a5 [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[]; };
extern int g1[5], g2[5], g3[5], g4[5], g5[5];
void sink (void*, ...);
ATTR (noipa) void*
return_2_locals (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
void *p = b;
if (i < 0)
p = a;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_2_locals_after_2_globals (int i, int j)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int *p;
if (i < 0)
p = g1;
else
p = g2;
sink (p);
if (j < 0)
p = a;
else
p = b;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_3_locals (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
void *p = b + 1;
if (i < 0)
p = a;
else if (0 < i)
p = c + 2;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_5_locals (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
int d[4]; /* { dg-message "declared here" } */
int e[5]; /* { dg-message "declared here" } */
void *p = &c[2];
if (i < -1)
p = a;
else if (i < 0)
p = &b[1];
else if (1 < i)
p = &e[4];
else if (0 < i)
p = &d[3];
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_5_locals_switch (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
int d[4]; /* { dg-message "declared here" } */
int e[5]; /* { dg-message "declared here" } */
void *p = 0;
switch (i)
{
case 0: p = &a[1]; break;
case 1: p = &b[2]; break;
case 2: p = &c[3]; break;
case 3: p = &d[4]; break;
default: p = &e[5]; break;
}
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_1_global_4_locals (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
int d[4]; /* { dg-message "declared here" } */
void *p = c;
if (i < -1)
sink (p = a);
else if (i < 0)
sink (p = b);
else if (1 < i)
sink (p = g1);
else if (0 < i)
sink (p = d);
sink (p, a, b, c, d);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_1_global_4_locals_switch (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
int d[4]; /* { dg-message "declared here" } */
void *p = 0;
switch (i)
{
case 0: p = &a[0]; break;
case 1: p = &b[1]; break;
case 2: p = &c[2]; break;
case 3: p = &d[3]; break;
}
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_2_globals_3_locals (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
void *p = c;
if (i < -1)
p = a;
else if (i < 0)
p = b;
else if (1 < i)
p = g1;
else if (0 < i)
p = g2;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_3_globals_2_locals (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
void *p = g3;
if (i < -1)
p = a;
else if (i < 0)
p = b;
else if (1 < i)
p = g1;
else if (0 < i)
p = g2;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_4_globals_1_local (int i)
{
int a[1]; /* { dg-message "declared here" } */
void *p = g3;
if (i < -1)
p = a;
else if (i < 0)
p = g1;
else if (1 < i)
p = g2;
else if (0 < i)
p = g4;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_all_globals (int i)
{
void *p = g4;
if (i < -1)
p = g1;
else if (i < 0)
p = g2;
else if (1 < i)
p = g3;
else if (0 < i)
p = g5;
return p;
}
ATTR (noipa) void*
return_2_alloca_local_cstoff (int n, int i)
{
int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
int *p = i < 0 ? a : b;
p += 1;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_alloca_local_cstoff (int n, int i)
{
int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int *p = b;
if (i < 0)
p = a;
p += 1;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_local_alloca_cstoff (int n, int i)
{
int a[2]; /* { dg-message "declared here" } */
int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
int *p = b;
if (i < 0)
p = a;
p += 1;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_2_locals_cstoff (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int *p = b;
if (i < 0)
p = a;
p += 1;
sink (p);
return p; /* { dg-warning "function returns address of local" } */
}
ATTR (noipa) void*
return_2_globals_3_locals_cstoff (int i)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int c[3]; /* { dg-message "declared here" } */
int *p = c;
if (i < -1)
p = a;
else if (i < 0)
p = b;
else if (1 < i)
p = g1;
else if (0 < i)
p = g2;
p += 1;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_3_globals_alloca_local_varoff (int n, int i, int j)
{
int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int *p = g3;
if (i < -1)
p = a;
else if (i < 0)
p = b;
else if (1 < i)
p = g1;
else if (0 < i)
p = g2;
p += j;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}
ATTR (noipa) void*
return_3_globals_2_locals_varoff (int i, int j)
{
int a[1]; /* { dg-message "declared here" } */
int b[2]; /* { dg-message "declared here" } */
int *p = g3;
if (i < -1)
p = a;
else if (i < 0)
p = b;
else if (1 < i)
p = g1;
else if (0 < i)
p = g2;
p += j;
sink (p);
return p; /* { dg-warning "function may return address of local" } */
}