// { dg-do run }
|
// { dg-do run }
|
// Test pointer chain catching
|
// Test pointer chain catching
|
// Copyright (C) 2000, 2002 Free Software Foundation, Inc.
|
// Copyright (C) 2000, 2002 Free Software Foundation, Inc.
|
// Contributed by Nathan Sidwell 9 Apr 2000
|
// Contributed by Nathan Sidwell 9 Apr 2000
|
|
|
#include
|
#include
|
|
|
void fn () {}
|
void fn () {}
|
struct A {void fn () {}};
|
struct A {void fn () {}};
|
static int var = 1;
|
static int var = 1;
|
static const int const_var = 2;
|
static const int const_var = 2;
|
|
|
struct B;
|
struct B;
|
struct C;
|
struct C;
|
|
|
int test0 ()
|
int test0 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw &fn;
|
throw &fn;
|
}
|
}
|
catch (void *)
|
catch (void *)
|
{
|
{
|
// should not decay to void *
|
// should not decay to void *
|
return 1;
|
return 1;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test1 ()
|
int test1 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw &A::fn;
|
throw &A::fn;
|
}
|
}
|
catch (void *)
|
catch (void *)
|
{
|
{
|
// should not decay to void *
|
// should not decay to void *
|
return 1;
|
return 1;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test2 ()
|
int test2 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw &var;
|
throw &var;
|
}
|
}
|
catch (void *)
|
catch (void *)
|
{
|
{
|
// should decay to void *
|
// should decay to void *
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test3 ()
|
int test3 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw &var;
|
throw &var;
|
}
|
}
|
catch (void const *)
|
catch (void const *)
|
{
|
{
|
// should decay to const void *
|
// should decay to const void *
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test4 ()
|
int test4 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw &const_var;
|
throw &const_var;
|
}
|
}
|
catch (void *)
|
catch (void *)
|
{
|
{
|
// should not decay to void *
|
// should not decay to void *
|
return 1;
|
return 1;
|
}
|
}
|
catch (void const *)
|
catch (void const *)
|
{
|
{
|
// should decay to const void *
|
// should decay to const void *
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 2;
|
return 2;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test5 ()
|
int test5 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw (void ***)0;
|
throw (void ***)0;
|
}
|
}
|
catch (void ***)
|
catch (void ***)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test6 ()
|
int test6 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw (void const* const* const*)0;
|
throw (void const* const* const*)0;
|
}
|
}
|
catch (void ***)
|
catch (void ***)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
catch (void * const* const*)
|
catch (void * const* const*)
|
{
|
{
|
return 2;
|
return 2;
|
}
|
}
|
catch (void const* * const*)
|
catch (void const* * const*)
|
{
|
{
|
return 3;
|
return 3;
|
}
|
}
|
catch (void const* const* *)
|
catch (void const* const* *)
|
{
|
{
|
return 4;
|
return 4;
|
}
|
}
|
catch (void const* const* const *)
|
catch (void const* const* const *)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test7 ()
|
int test7 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw (void ***)0;
|
throw (void ***)0;
|
}
|
}
|
catch (void const* const**)
|
catch (void const* const**)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
catch (void const** const *)
|
catch (void const** const *)
|
{
|
{
|
return 2;
|
return 2;
|
}
|
}
|
catch (void * const* const *)
|
catch (void * const* const *)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 3;
|
return 3;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test8 ()
|
int test8 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw (B **)0;
|
throw (B **)0;
|
}
|
}
|
catch (C **)
|
catch (C **)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
catch (B **)
|
catch (B **)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 2;
|
return 2;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
int test9 ()
|
int test9 ()
|
{
|
{
|
try
|
try
|
{
|
{
|
throw (B **)0;
|
throw (B **)0;
|
}
|
}
|
catch (C const *const *)
|
catch (C const *const *)
|
{
|
{
|
return 1;
|
return 1;
|
}
|
}
|
catch (B const *const *)
|
catch (B const *const *)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
catch (...)
|
catch (...)
|
{
|
{
|
return 2;
|
return 2;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
static int (*tests[])() =
|
static int (*tests[])() =
|
{
|
{
|
test0,
|
test0,
|
test1,
|
test1,
|
test2,
|
test2,
|
test3,
|
test3,
|
test4,
|
test4,
|
|
|
test5,
|
test5,
|
test6,
|
test6,
|
test7,
|
test7,
|
|
|
test8,
|
test8,
|
test9,
|
test9,
|
|
|
NULL
|
NULL
|
};
|
};
|
|
|
int main ()
|
int main ()
|
{
|
{
|
int ix;
|
int ix;
|
int errors = 0;
|
int errors = 0;
|
|
|
for (ix = 0; tests[ix]; ix++)
|
for (ix = 0; tests[ix]; ix++)
|
{
|
{
|
int n = tests[ix] ();
|
int n = tests[ix] ();
|
|
|
if (n)
|
if (n)
|
{
|
{
|
printf ("test %d failed %d\n", ix, n);
|
printf ("test %d failed %d\n", ix, n);
|
errors++;
|
errors++;
|
}
|
}
|
}
|
}
|
return errors;
|
return errors;
|
}
|
}
|
|
|