From 26f63d2d82d22f568ba44d12d396acca8aa11613 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Sun, 19 Jul 2015 17:08:17 +0200 Subject: Test to check that alias analysis is prudently conservative on ill-defined pointer manipulations. --- test/regression/alias.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 test/regression/alias.c (limited to 'test/regression/alias.c') diff --git a/test/regression/alias.c b/test/regression/alias.c new file mode 100644 index 00000000..c9eb8130 --- /dev/null +++ b/test/regression/alias.c @@ -0,0 +1,145 @@ +/* Testing the alias analysis on ill-defined codes + where it should remain conservative. */ + +typedef unsigned int uintptr_t; + +/* For testing with GCC */ +#define NOINLINE __attribute__((noinline)) + +/* Passing a pointer through a long long */ + +void NOINLINE set1(long long x) +{ + int * p = (int *) (uintptr_t) x; + *p = 1; +} + +int get1(void) +{ + int x = 0; + set1((uintptr_t) &x); + return x; +} + +/* Passing a pointer through a double */ + +void NOINLINE set2(double x) +{ + int * p = (int *) (uintptr_t) x; + *p = 1; +} + +int get2(void) +{ + int x = 0; + set2((uintptr_t) &x); + return x; +} + +/* Tagging a pointer */ + +void NOINLINE set3(uintptr_t x) +{ + int * p = (int *) (x & ~1); + *p = 1; +} + +int get3(void) +{ + int x = 0; + set3((uintptr_t) &x | 1); + return x; +} + +/* XOR-ing a pointer */ + +static uintptr_t key = 0xDEADBEEF; + +void NOINLINE set4(uintptr_t x) +{ + int * p = (int *) (x ^ key); + *p = 1; +} + +int get4(void) +{ + int x = 0; + set4((uintptr_t) &x ^ key); + return x; +} + +/* Byte-swapping a pointer */ + +inline uintptr_t bswap(uintptr_t x) +{ + return (x >> 24) + | (((x >> 16) & 0xFF) << 8) + | (((x >> 8) & 0xFF) << 16) + | ((x & 0xFF) << 24); +} + +void NOINLINE set5(uintptr_t x) +{ + int * p = (int *) bswap(x); + *p = 1; +} + +int get5(void) +{ + int x = 0; + set5(bswap((uintptr_t) &x)); + return x; +} + +/* Even more fun with xor */ + +int x; + +void NOINLINE set6(int * p, uintptr_t z) +{ + int * q = (int *) ((uintptr_t) p ^ z); + *q = 1; +} + +int get6(void) +{ + int y = 0; + uintptr_t z = (uintptr_t) &x ^ (uintptr_t) &y; + set6(&x, z); + int res1 = y; + x = 0; + set6(&y, z); + int res2 = x; + return res1 & res2; +} + +/* Aligning pointers the hard way */ + +int offset = 3; /* but not const */ + +int get7(void) +{ + union { int i; char c[4]; } u; /* force alignment to 4 */ + u.c[0] = 0; + uintptr_t x = (uintptr_t) &(u.c[offset]); + x = x & ~3; + *((char *) x) = 1; + return u.c[0]; +} + +/* Test harness */ + +#include + +int main() +{ + printf("Test 1: %d\n", get1()); + printf("Test 2: %d\n", get2()); + printf("Test 3: %d\n", get3()); + printf("Test 4: %d\n", get4()); + printf("Test 5: %d\n", get5()); + printf("Test 6: %d\n", get6()); + printf("Test 7: %d\n", get7()); + return 0; +} + -- cgit