blob: 94dc3508f1adb46678271e466c2f566e8a34a8f5 [file] [log] [blame]
/* Test that stack protection is done on chosen functions. */
/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */
/* { dg-options "-O2 -fstack-protector-strong" } */
/* This test checks the presence of __stack_chk_fail function in assembler.
* Compiler generates _stack_chk_fail_local (wrapper) calls instead for PIC.
*/
/* { dg-require-effective-target nonpic } */
#include<string.h>
extern int g0;
extern int* pg0;
int
goo (int *);
int
hoo (int);
/* Function frame address escaped function call. */
int
foo1 ()
{
int i;
return goo (&i);
}
struct ArrayStruct
{
int a;
int array[10];
};
struct AA
{
int b;
struct ArrayStruct as;
};
/* Function frame contains array. */
int
foo2 ()
{
struct AA aa;
int i;
for (i = 0; i < 10; ++i)
{
aa.as.array[i] = i * (i-1) + i / 2;
}
return aa.as.array[5];
}
/* Address computation based on a function frame address. */
int
foo3 ()
{
int a;
int *p;
p = &a + 5;
return goo (p);
}
/* Address cast based on a function frame address. */
int
foo4 ()
{
int a;
return goo (g0 << 2 ? (int *)(3 * (long)(void *)(&a)) : 0);
}
/* Address cast based on a local array. */
int
foo5 ()
{
short array[10];
return goo ((int *)(array + 5));
}
struct BB
{
int one;
int two;
int three;
};
/* Address computaton based on a function frame address.*/
int
foo6 ()
{
struct BB bb;
return goo (&bb.one + sizeof(int));
}
/* Function frame address escaped via global variable. */
int
foo7 ()
{
int a;
pg0 = &a;
goo (pg0);
return *pg0;
}
/* Check that this covers -fstack-protector. */
int
foo8 ()
{
char base[100];
memcpy ((void *)base, (const void *)pg0, 105); /* { dg-warning "writing 105 bytes into a region of size 100" } */
return (int)(base[32]);
}
/* Check that this covers -fstack-protector. */
int
foo9 ()
{
char* p = __builtin_alloca (100);
return goo ((int *)(p + 50));
}
int
global2 (struct BB* pbb);
/* Address taken on struct. */
int
foo10 ()
{
struct BB bb;
int i;
bb.one = global2 (&bb);
for (i = 0; i < 10; ++i)
{
bb.two = bb.one + bb.two;
bb.three = bb.one + bb.two + bb.three;
}
return bb.three;
}
struct B
{
/* Discourage passing this struct in registers. */
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
};
struct B global3 (void);
int foo11 ()
{
return global3 ().a1;
}
void foo12 ()
{
global3 ();
}
/* { dg-final { scan-assembler-times "stack_chk_fail" 12 } } */