summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/torture/stackalign
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/torture/stackalign
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/torture/stackalign')
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/check.h36
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C57
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C43
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C40
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C40
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C58
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-thiscall-1.C43
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C73
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C79
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp35
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C17
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h142
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-1.C62
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-2.C53
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-3.C52
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/throw-4.C55
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C12
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C16
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C29
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C35
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C17
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C31
-rw-r--r--gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C31
23 files changed, 1056 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/check.h b/gcc/testsuite/g++.dg/torture/stackalign/check.h
new file mode 100644
index 000000000..af1988512
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/check.h
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+int
+check_int (int *i, int align)
+{
+ *i = 20;
+ if ((((ptrdiff_t) i) & (align - 1)) != 0)
+ {
+#ifdef DEBUG
+ printf ("\nUnalign address (%d): %p!\n", align, i);
+#endif
+ abort ();
+ }
+ return *i;
+}
+
+void
+check (void *p, int align)
+{
+ if ((((ptrdiff_t) p) & (align - 1)) != 0)
+ {
+#ifdef DEBUG
+ printf ("\nUnalign address (%d): %p!\n", align, p);
+#endif
+ abort ();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C
new file mode 100644
index 000000000..89b0a6a67
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+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) throw (B,A)
+{
+ char *p = (char*) __builtin_alloca (size + 1);
+ aligned i;
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C
new file mode 100644
index 000000000..4b849a2e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C
@@ -0,0 +1,43 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+__attribute__ ((fastcall))
+void
+foo (int j, int k, int m, int n, int o) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (1, 2, 3, 4, 5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C
new file mode 100644
index 000000000..cc05ed04f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+foo (void) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C
new file mode 100644
index 000000000..d2555f2e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+static void
+inline __attribute__((always_inline))
+foo (void) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C
new file mode 100644
index 000000000..1cbc68cc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C
@@ -0,0 +1,58 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+static void
+inline __attribute__((always_inline))
+foo (int size) throw (B,A)
+{
+ char *p = (char *) __builtin_alloca (size + 1);
+ aligned i;
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-thiscall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-thiscall-1.C
new file mode 100644
index 000000000..de9bed55c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-thiscall-1.C
@@ -0,0 +1,43 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+__attribute__ ((thiscall))
+void
+foo (int j, int k, int m, int n, int o) throw (B,A)
+{
+ aligned i;
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5)
+ abort ();
+
+ throw A();
+}
+
+int
+main()
+{
+ try { foo (1, 2, 3, 4, 5); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C
new file mode 100644
index 000000000..b9ba81b12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C
@@ -0,0 +1,73 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+foo (const char *fmt, ...) throw (B,A)
+{
+ va_list arg;
+ char *p;
+ aligned i;
+ int size;
+ double x;
+
+ va_start (arg, fmt);
+ size = va_arg (arg, int);
+ if (size != 5)
+ abort ();
+ p = (char *) __builtin_alloca (size + 1);
+
+ x = va_arg (arg, double);
+ if (x != 5.0)
+ abort ();
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+
+ va_end (arg);
+}
+
+int
+main()
+{
+ try { foo ("foo", 5, 5.0); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C
new file mode 100644
index 000000000..5e282179c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C
@@ -0,0 +1,79 @@
+/* { dg-options "-Wno-abi" {target arm_eabi} } */
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+ A() {}
+};
+
+struct B {};
+
+void
+test (va_list arg) throw (B,A)
+{
+ char *p;
+ aligned i;
+ int size;
+ double x;
+
+ size = va_arg (arg, int);
+ if (size != 5)
+ abort ();
+
+ p = (char *) __builtin_alloca (size + 1);
+
+ x = va_arg (arg, double);
+ if (x != 5.0)
+ abort ();
+
+ bar (p, size);
+ if (__builtin_strncmp (p, "good", size) != 0)
+ {
+#ifdef DEBUG
+ p[size] = '\0';
+ printf ("Failed: %s != good\n", p);
+#endif
+ abort ();
+ }
+
+ if (check_int (&i, __alignof__(i)) != i)
+ abort ();
+
+ throw A();
+}
+
+void
+foo (const char *fmt, ...)
+{
+ va_list arg;
+ va_start (arg, fmt);
+ test (arg);
+ va_end (arg);
+}
+int
+main()
+{
+ try { foo ("foo", 5, 5.0); }
+ catch (A& a) { }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp
new file mode 100644
index 000000000..3d0609fc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2008, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib g++-dg.exp
+dg-init
+set additional_flags ""
+
+# If automatic stack alignment is supported, force it on.
+if { [check_effective_target_automatic_stack_alignment] } then {
+ lappend additional_flags "-mstackrealign"
+ lappend additional_flags "-mpreferred-stack-boundary=5"
+}
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags
+if { [check_effective_target_fpic] } then {
+ lappend additional_flags "-fpic"
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags
+}
+dg-finish
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C
new file mode 100644
index 000000000..393b37e7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+
+// This case is to detect an assertion failure in stack branch development.
+
+bool f();
+struct S {
+ __attribute__ ((stdcall)) ~S();
+};
+void g() {
+ for (;;) {
+ S s1, s2, s3;
+ if (f())
+ continue;
+ if (f())
+ return;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h
new file mode 100644
index 000000000..ff5602784
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h
@@ -0,0 +1,142 @@
+#include "check.h"
+
+
+#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) STRING (prefix) cname
+#define STRING(x) #x
+
+#ifdef __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+extern void foo(void);
+
+#define INIT_EDI 1
+#define INIT_ESI 2
+#define INIT_EBX 3
+
+/* Set DI/SI/BX to wrong value
+ Use following template so that RA will save/restore callee
+ save registers in prologue/epilogue */
+#define ALTER_REGS() \
+ { \
+ int dummy; \
+ __asm__ __volatile__ (\
+ "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\
+ );\
+ __asm__ __volatile__ (\
+ "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\
+ );\
+ __asm__ __volatile__ (\
+ "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\
+ );\
+ }
+
+#if defined __PIC__ || defined __USING_SJLJ_EXCEPTIONS__
+int
+main ()
+{
+ return 0;
+}
+#else
+void __attribute__ ((noinline))
+copy (char *p, int size)
+{
+ __builtin_strncpy (p, "good", size);
+}
+
+int g_edi __attribute__((externally_visible)) =INIT_EDI;
+int g_esi __attribute__((externally_visible)) =INIT_ESI;
+int g_ebx __attribute__((externally_visible)) = INIT_EBX;
+int g_ebp __attribute__((externally_visible));
+int g_esp __attribute__((externally_visible));
+int g_ebp_save __attribute__((externally_visible));
+int g_esp_save __attribute__((externally_visible));
+int n_error;
+
+int
+main()
+{
+ int dummy;
+ // Init registers to correct value.
+ // Use following template so that RA will save/restore callee
+ // save registers in prologue/epilogue
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=D" (dummy)
+ : "i" (INIT_EDI)
+ );
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=S" (dummy)
+ : "i" (INIT_ESI)
+ );
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=b" (dummy)
+ : "i" (INIT_EBX)
+ );
+ __asm__ __volatile__ (
+ "movl %ebp," ASMNAME("g_ebp_save")"\n\t"
+ "movl %esp," ASMNAME("g_esp_save")"\n\t"
+ );
+ try {
+ foo();
+ }
+ catch (...)
+ {
+ }
+
+ // Get DI/SI/BX register value after exception caught
+ __asm__ __volatile__ (
+ "movl %edi," ASMNAME("g_edi")"\n\t"
+ "movl %esi," ASMNAME("g_esi")"\n\t"
+ "movl %ebx," ASMNAME("g_ebx")"\n\t"
+ "movl %ebp," ASMNAME("g_ebp")"\n\t"
+ "movl %esp," ASMNAME("g_esp")"\n\t"
+ );
+
+ // Check if DI/SI/BX register value are the same as before calling
+ // foo.
+ if (g_edi != INIT_EDI)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI);
+#endif
+ }
+ if (g_esi != INIT_ESI)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI);
+#endif
+ }
+ if (g_ebx != INIT_EBX)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX);
+#endif
+ }
+ if (g_ebp != g_ebp_save)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save);
+#endif
+ }
+ if (g_esp != g_esp_save)
+ {
+ n_error++;
+#ifdef DEBUG
+ printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save);
+#endif
+ }
+ if (n_error !=0)
+ abort();
+ return 0;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C
new file mode 100644
index 000000000..3eddc1d02
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C
@@ -0,0 +1,62 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k,l,m,n;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ for (k=0; k < j; k++)
+ for (l=0; l < k; l++)
+ for (m=0; m < l; m++)
+ for (n=0; n < m; n++)
+ global2 = k;
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+ throw 0;
+}
+
+void foo()
+{
+ bar();
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ foo();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C
new file mode 100644
index 000000000..63a8c6e7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ global2 = k;
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+ throw 0;
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ bar ();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C
new file mode 100644
index 000000000..d3e53b829
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ global2 = k;
+ throw 0;
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ bar ();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C
new file mode 100644
index 000000000..52e6f7ff7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+/* { dg-skip-if "Stack alignment is too small" { hppa*-*-hpux* } "*" "" } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT 64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+ volatile t_align a = 1;
+ int i,j,k;
+ i=j=k=0;
+ for (i=0; i < global; i++)
+ for (j=0; j < i; j++)
+ {
+ global2 = k;
+ throw 0;
+ }
+ if (check_int ((int *) &a, __alignof__(a)) != a)
+ abort ();
+}
+
+int main()
+{
+ int ll = 1;
+ int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+ try {
+ for (; i < global; i++)
+ for (; j < i; j++)
+ for (; k < j; k++)
+ for (; l < k; l++)
+ for (; m < l; m++)
+ for (; n < m; n++)
+ global2 = k;
+ bar ();
+ }
+ catch (...)
+ {
+ }
+ ll = i+j+k+l+m+n;
+ if (ll != 15)
+ {
+#ifdef DEBUG
+ printf("FAIL: sum %d != 15\n", ll);
+#endif
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C
new file mode 100644
index 000000000..f8166eb95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C
@@ -0,0 +1,12 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+void __attribute__ ((noinline)) foo()
+{
+ ALTER_REGS();
+ // Throw the except and expect returning to main
+ throw 1;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C
new file mode 100644
index 000000000..70dce7485
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C
@@ -0,0 +1,16 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+/* Test situation 1: Stack really realign without DRAP */
+void __attribute__ ((noinline))
+foo ()
+{
+ int __attribute__ ((aligned(64))) a=1;
+ if (check_int (&a, __alignof__(a)) != a)
+ abort ();
+ ALTER_REGS();
+ throw a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C
new file mode 100644
index 000000000..791eeb551
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C
@@ -0,0 +1,29 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+/* Test situation 2: stack really realign with DRAP reg CX */
+void __attribute__ ((noinline))
+foo ()
+{
+ int __attribute__ ((aligned(64))) a=4;
+ char * s = (char *) __builtin_alloca (a + 1);
+
+ copy (s, a);
+ if (__builtin_strncmp (s, "good", a) != 0)
+ {
+#ifdef DEBUG
+ s[a] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+
+ if (check_int (&a, __alignof__(a)) != a)
+ abort ();
+
+ ALTER_REGS();
+ throw a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C
new file mode 100644
index 000000000..29dee2d5a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C
@@ -0,0 +1,35 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+/* Test situation 3: Stack realign really happen with DRAP reg DI */
+void __attribute__ ((noinline)) __attribute__ ((regparm(3)))
+bar (int arg1, int arg2, int arg3)
+{
+ int __attribute__ ((aligned(64))) a=1;
+ char * s = (char *) __builtin_alloca (arg3 + 1);
+
+ copy (s, arg3);
+ if (__builtin_strncmp (s, "good", arg3) != 0)
+ {
+#ifdef DEBUG
+ s[arg3] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+
+ if (check_int (&a, __alignof__(a)) != a)
+ abort ();
+
+ ALTER_REGS();
+ throw arg1+arg2+arg3+a;
+}
+
+void
+foo()
+{
+ bar (1,2,3);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C
new file mode 100644
index 000000000..a896176ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C
@@ -0,0 +1,17 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+volatile int __attribute__ ((aligned(32))) g_a=1;
+/* Test situation 4: no Drap and stack realign doesn't really happen */
+void __attribute__ ((noinline))
+foo()
+{
+ int i;
+ ALTER_REGS();
+ for (i=0; i < 10; i++)
+ g_a++;
+ throw g_a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C
new file mode 100644
index 000000000..514e4e77a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+double g_f=1.0;
+/* Test situation 5: Stack realign dosn't really happen with DRAP reg CX */
+void __attribute__ ((noinline)) __attribute__ ((regparm(2)))
+bar(int arg1, int arg2, int arg3, int arg4)
+{
+ char * s = (char *) __builtin_alloca (arg4 + 1);
+
+ copy (s, arg4);
+ if (__builtin_strncmp (s, "good", arg4) != 0)
+ {
+#ifdef DEBUG
+ s[arg4] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+ ALTER_REGS();
+ if (g_f) throw arg1+arg2+arg3+ g_f;
+}
+
+void __attribute__((noinline))
+foo()
+{
+ bar(1,2,3,4);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C
new file mode 100644
index 000000000..a888ca1b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#if !defined __PIC__ && !defined __USING_SJLJ_EXCEPTIONS__
+double g_f=1.0;
+/* Test situation 6: Stack realign dosn't really happen with DRAP reg DI */
+void __attribute__ ((noinline)) __attribute__ ((regparm(3)))
+bar(int arg1, int arg2, int arg3, int arg4)
+{
+ char * s = (char *) __builtin_alloca (arg4 + 1);
+
+ copy (s, arg4);
+ if (__builtin_strncmp (s, "good", arg4) != 0)
+ {
+#ifdef DEBUG
+ s[arg4] = '\0';
+ printf ("Failed: %s != good\n", s);
+#endif
+ abort ();
+ }
+ ALTER_REGS();
+ if (g_f) throw arg1+arg2+arg3+ g_f;
+}
+
+void __attribute__((noinline))
+foo()
+{
+ bar(1,2,3,4);
+}
+#endif