// Try to check that registers are preserved when the stack is unwound. // { dg-do run } // { dg-options -O2 } extern "C" void exit(int); extern "C" void abort(); // This test case triggers up to DEPTH recursive calls to function // foo(), These calls are numbered so that 0 is the innermost, 1 the // second innermost, and so on. Each call caches NUM_VARS elements of // both DOUBLE_SRC and INT_SRC and applies a trivial operation to each // cached value. The innermost foo() call will throw an integer call // number. The specified call should store its cached values in // DOUBLE_DEST and INT_DEST, which main() will check. const int num_vars = 16; const int depth = 3; float float_src[num_vars * depth]; float float_dest[num_vars]; int int_src[num_vars * depth]; int int_dest[num_vars]; void foo (int level, int throw_to) { float *fsrc = &float_src[level * num_vars]; float f00 = *fsrc++ + 1.0f; float f01 = *fsrc++ + 1.0f; float f02 = *fsrc++ + 1.0f; float f03 = *fsrc++ + 1.0f; float f04 = *fsrc++ + 1.0f; float f05 = *fsrc++ + 1.0f; float f06 = *fsrc++ + 1.0f; float f07 = *fsrc++ + 1.0f; float f08 = *fsrc++ + 1.0f; float f09 = *fsrc++ + 1.0f; float f10 = *fsrc++ + 1.0f; float f11 = *fsrc++ + 1.0f; float f12 = *fsrc++ + 1.0f; float f13 = *fsrc++ + 1.0f; float f14 = *fsrc++ + 1.0f; float f15 = *fsrc++ + 1.0f; int *isrc = &int_src[level * num_vars]; int i00 = *isrc++ + 1; int i01 = *isrc++ + 1; int i02 = *isrc++ + 1; int i03 = *isrc++ + 1; int i04 = *isrc++ + 1; int i05 = *isrc++ + 1; int i06 = *isrc++ + 1; int i07 = *isrc++ + 1; int i08 = *isrc++ + 1; int i09 = *isrc++ + 1; int i10 = *isrc++ + 1; int i11 = *isrc++ + 1; int i12 = *isrc++ + 1; int i13 = *isrc++ + 1; int i14 = *isrc++ + 1; int i15 = *isrc++ + 1; try { if (level == 0) throw throw_to; else foo (level - 1, throw_to); } catch (int i) { if (i == level) { float *fdest = float_dest; *fdest++ = f00; *fdest++ = f01; *fdest++ = f02; *fdest++ = f03; *fdest++ = f04; *fdest++ = f05; *fdest++ = f06; *fdest++ = f07; *fdest++ = f08; *fdest++ = f09; *fdest++ = f10; *fdest++ = f11; *fdest++ = f12; *fdest++ = f13; *fdest++ = f14; *fdest++ = f15; int *idest = int_dest; *idest++ = i00; *idest++ = i01; *idest++ = i02; *idest++ = i03; *idest++ = i04; *idest++ = i05; *idest++ = i06; *idest++ = i07; *idest++ = i08; *idest++ = i09; *idest++ = i10; *idest++ = i11; *idest++ = i12; *idest++ = i13; *idest++ = i14; *idest++ = i15; } else { throw; } } } int main () { for (int i = 0; i < depth * num_vars; i++) { int_src[i] = i * i; float_src[i] = i * 2.0f; } for (int level = 0; level < depth; level++) for (int throw_to = 0; throw_to <= level; throw_to++) { foo (level, throw_to); float *fsrc = &float_src[throw_to * num_vars]; int *isrc = &int_src[throw_to * num_vars]; for (int i = 0; i < num_vars; i++) { if (int_dest[i] != isrc[i] + 1) abort (); if (float_dest[i] != fsrc[i] + 1.0f) abort (); } } exit (0); }