diff --git a/SingleSource/UnitTests/dyn_stack_alloc_realign.cpp b/SingleSource/UnitTests/dyn_stack_alloc_realign.cpp new file mode 100644 --- /dev/null +++ b/SingleSource/UnitTests/dyn_stack_alloc_realign.cpp @@ -0,0 +1,59 @@ +#include +#include + +int checkInt(int *I, int Align) { + *I = 20; + if ((((size_t)I) & (Align - 1)) != 0) { + printf("\nUnalign address (%d): %p!\n", Align, I); + abort(); + } + return *I; +} + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +void bar(char *p, int size) { __builtin_strncpy(p, "good", size); } + +class Base {}; + +struct A : virtual public Base { + A() {} +}; + +struct B {}; + +void foo(int size) { + aligned Var; + char *Ptr = (char *)__builtin_alloca(size + 1); + aligned I; + + // clobber 32-bit base pointer. + asm volatile("nop" ::"S"(405) :); + // clobber 64-bit base pointer. + asm volatile("nop" ::"b"(405) :); + bar(Ptr, size); + if (__builtin_strncmp(Ptr, "good", size) != 0) { + Ptr[size] = '\0'; + printf("Failed: %s != good\n", Ptr); + abort(); + } + + if (checkInt(&I, __alignof__(I)) != I) + abort(); + + // access argument and local variable. + asm volatile("movl %0, %1" ::"r"(size), "m"(Var) :); + throw A(); +} + +int main() { + try { + foo(5); + } catch (A &a) { + } + return 0; +} diff --git a/SingleSource/UnitTests/dyn_stack_alloc_realign.reference_output b/SingleSource/UnitTests/dyn_stack_alloc_realign.reference_output new file mode 100644 --- /dev/null +++ b/SingleSource/UnitTests/dyn_stack_alloc_realign.reference_output @@ -0,0 +1 @@ +exit 0 diff --git a/SingleSource/UnitTests/dyn_stack_alloc_realign2.cpp b/SingleSource/UnitTests/dyn_stack_alloc_realign2.cpp new file mode 100644 --- /dev/null +++ b/SingleSource/UnitTests/dyn_stack_alloc_realign2.cpp @@ -0,0 +1,59 @@ +#include +#include + +int checkInt(int *I, int Align) { + *I = 20; + if ((((size_t)I) & (Align - 1)) != 0) { + printf("\nUnalign address (%d): %p!\n", Align, I); + abort(); + } + return *I; +} + +#ifndef ALIGNMENT +#define ALIGNMENT 64 +#endif + +typedef int aligned __attribute__((aligned(ALIGNMENT))); + +void bar(char *p, int size) { __builtin_strncpy(p, "good", size); } + +class Base {}; + +struct A : virtual public Base { + A() {} +}; + +struct B {}; + +__attribute__((noinline)) +void foo(int size) { + aligned Var; + char *Ptr = (char *)__builtin_alloca(size + 1); + aligned I; + + // clobber 32-bit base pointer. + asm volatile("nop" ::"S"(405) :); + // clobber 64-bit base pointer. + asm volatile("nop" ::"b"(405) :); + bar(Ptr, size); + if (__builtin_strncmp(Ptr, "good", size) != 0) { + Ptr[size] = '\0'; + printf("Failed: %s != good\n", Ptr); + abort(); + } + + if (checkInt(&I, __alignof__(I)) != I) + abort(); + + // access argument and local variable. + asm volatile("movl %0, %1" ::"r"(size), "m"(Var) :); +} + +int main() { + try { + foo(5); + } catch (A &a) { + } + return 0; +} diff --git a/SingleSource/UnitTests/dyn_stack_alloc_realign2.reference_output b/SingleSource/UnitTests/dyn_stack_alloc_realign2.reference_output new file mode 100644 --- /dev/null +++ b/SingleSource/UnitTests/dyn_stack_alloc_realign2.reference_output @@ -0,0 +1 @@ +exit 0