diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10bff5d6de23f473e538272cc2e43a06f77f6f56..87c5774c9761e729b61bf0d60cfffa5711b567d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2003-05-07 Richard Henderson <rth@redhat.com> + + PR c++/10570 + * except.c: Revert 04-01 and 04-02 forced-unwind changes. + * flags.h, toplev.c, doc/invoke.texi: Likewise. + + * unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning. + * unwind.inc (_Unwind_DeleteException): Check for null + exception_cleanup. + + * unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New. + * unwind.inc (_Unwind_Resume_or_Rethrow): New. + * unwind.h: Declare them. + * libgcc-std.ver (GCC_3.3): Export them. + 2003-05-07 Richard Henderson <rth@redhat.com> * unwind-dw2.c (_Unwind_GetCFA): Cast pointer to _Unwind_Ptr, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4955d64a83e21283beac9f185c763daf0ffbec0e..f4e3e7e7bef34c9aa2609f0d5404c5cb27b8d3c7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2003-05-07 Richard Henderson <rth@redhat.com> + + PR c++/10570 + * cfns.gperf: Comment out POSIX thread cancellation points, + plus abort and raise. + * cfns.h: Regenerate. + 2003-05-07 Jason Merrill <jason@redhat.com> * call.c (build_conditional_expr): Don't assume that the folded diff --git a/gcc/cp/cfns.gperf b/gcc/cp/cfns.gperf index 850b66a1959a520ed3aabe5585c82dcc8a999437..6ee56b5ea531cf6761e5b0b640995a50afb13bd3 100644 --- a/gcc/cp/cfns.gperf +++ b/gcc/cp/cfns.gperf @@ -16,9 +16,9 @@ const char * libc_name_p (const char *, unsigned int); # exception, unless it calls a program-supplied function that # throws an exception. # -# bsearch and qsort are commented out because they can call such functions. +# Specific functions are commented out for the reason noted in each case. # -abort +# abort -- synchronous exception from SIGABRT handler abs acos asctime @@ -29,7 +29,7 @@ atexit atof atoi atol -#bsearch +#bsearch -- calls user function which may throw exception btowc calloc ceil @@ -43,41 +43,41 @@ div exit exp fabs -fclose +#fclose -- POSIX thread cancellation point feof ferror -fflush -fgetc -fgetpos -fgets -fgetwc -fgetws +#fflush -- POSIX thread cancellation point +#fgetc -- POSIX thread cancellation point +#fgetpos -- POSIX thread cancellation point +#fgets -- POSIX thread cancellation point +#fgetwc -- POSIX thread cancellation point +#fgetws -- POSIX thread cancellation point floor fmod -fopen -fprintf -fputc -fputs -fputwc -fputws -fread +#fopen -- POSIX thread cancellation point +#fprintf -- POSIX thread cancellation point +#fputc -- POSIX thread cancellation point +#fputs -- POSIX thread cancellation point +#fputwc -- POSIX thread cancellation point +#fputws -- POSIX thread cancellation point +#fread -- POSIX thread cancellation point free -freopen +#freopen -- POSIX thread cancellation point frexp -fscanf +#fscanf -- POSIX thread cancellation point fseek -fsetpos -ftell +#fsetpos -- POSIX thread cancellation point +#ftell -- POSIX thread cancellation point fwide -fwprintf -fwrite -fwscanf -getc -getchar +#fwprintf -- POSIX thread cancellation point +#fwrite -- POSIX thread cancellation point +#fwscanf -- POSIX thread cancellation point +#getc -- POSIX thread cancellation point +#getchar -- POSIX thread cancellation point getenv -gets -getwc -getwchar +#gets -- POSIX thread cancellation point +#getwc -- POSIX thread cancellation point +#getwchar -- POSIX thread cancellation point gmtime isalnum isalpha @@ -125,22 +125,22 @@ memmove memset mktime modf -perror +#perror -- POSIX thread cancellation point pow -printf -putc -putchar -puts -putwc -putwchar -#qsort -raise +#printf -- POSIX thread cancellation point +#putc -- POSIX thread cancellation point +#putchar -- POSIX thread cancellation point +#puts -- POSIX thread cancellation point +#putwc -- POSIX thread cancellation point +#putwchar -- POSIX thread cancellation point +#qsort -- calls user function which may throw exception +#raise -- synchronous exception from signal handler rand realloc -remove -rename -rewind -scanf +#remove -- POSIX thread cancellation point +#rename -- POSIX thread cancellation point +#rewind -- POSIX thread cancellation point +#scanf -- POSIX thread cancellation point setbuf setlocale setvbuf @@ -157,7 +157,7 @@ strcmp strcoll strcpy strcspn -strerror +#strerror -- POSIX thread cancellation point strftime strlen strncat @@ -174,25 +174,25 @@ strtoul strxfrm swprintf swscanf -system +#system -- POSIX thread cancellation point tan tanh time -tmpfile -tmpnam +#tmpfile -- POSIX thread cancellation point +#tmpnam -- POSIX thread cancellation point tolower toupper towctrans towlower towupper -ungetc -ungetwc -vfprintf -vfwprintf -vprintf +#ungetc -- POSIX thread cancellation point +#ungetwc -- POSIX thread cancellation point +#vfprintf -- POSIX thread cancellation point +#vfwprintf -- POSIX thread cancellation point +#vprintf -- POSIX thread cancellation point vsprintf vswprintf -vwprintf +#vwprintf -- POSIX thread cancellation point wcrtomb wcscat wcschr @@ -225,5 +225,5 @@ wmemcmp wmemcpy wmemmove wmemset -wprintf -wscanf +#wprintf -- POSIX thread cancellation point +#wscanf -- POSIX thread cancellation point diff --git a/gcc/cp/cfns.h b/gcc/cp/cfns.h index e4200947eb38c2179595fa51069c8c8ba68a852e..8f8f3eaa35a92a1de0559159fdd9263ef3ed7edb 100644 --- a/gcc/cp/cfns.h +++ b/gcc/cp/cfns.h @@ -1,5 +1,5 @@ /* C code produced by gperf version 2.7.2 */ -/* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p ../../gcc/gcc/cp/cfns.gperf */ +/* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p ../../../src-gcc/gcc/cp/cfns.gperf */ #ifdef __GNUC__ __inline #endif @@ -8,7 +8,7 @@ static unsigned int hash (const char *, unsigned int); __inline #endif const char * libc_name_p (const char *, unsigned int); -/* maximum key range = 1020, duplicates = 1 */ +/* maximum key range = 480, duplicates = 1 */ #ifdef __GNUC__ __inline @@ -24,32 +24,32 @@ hash (str, len) { static const unsigned short asso_values[] = { - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 0, 1, - 0, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 247, 218, 144, - 0, 0, 40, 7, 126, 184, 2, 15, 146, 67, - 9, 60, 0, 0, 3, 0, 7, 8, 197, 1, - 40, 8, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038 + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 0, 0, + 1, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 106, 76, 0, + 21, 0, 0, 11, 43, 26, 0, 66, 106, 17, + 121, 0, 17, 0, 7, 0, 3, 19, 49, 1, + 3, 41, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483 }; register int hval = len; @@ -83,356 +83,236 @@ libc_name_p (str, len) { enum { - TOTAL_KEYWORDS = 207, + TOTAL_KEYWORDS = 156, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 10, - MIN_HASH_VALUE = 18, - MAX_HASH_VALUE = 1037 + MIN_HASH_VALUE = 3, + MAX_HASH_VALUE = 482 }; static const char * const wordlist[] = { - "gets", - "puts", - "sqrt", - "strerror", - "strstr", - "strspn", - "exp", + "cos", + "feof", "free", - "fgets", - "fputs", - "fgetws", - "fputws", + "sqrt", + "wcsrtombs", "pow", - "fseek", - "perror", - "strtod", - "toupper", - "towupper", - "frexp", - "strtok", - "fsetpos", + "towctrans", + "wcsstr", + "wcstombs", + "strstr", "ferror", - "freopen", - "fgetpos", - "fopen", + "wcsxfrm", + "wcsftime", + "exit", + "exp", + "modf", + "strxfrm", "wmemset", "memset", - "system", - "wcsstr", - "wctype", - "strxfrm", - "wcsspn", - "strcspn", - "fmod", - "strcpy", - "strncpy", - "strlen", - "ungetwc", - "feof", - "ldexp", - "isupper", - "rewind", - "iswupper", - "sin", - "cos", - "modf", - "iswpunct", - "wcstod", - "log10", - "log", - "wcsrtombs", - "strcmp", - "fwide", - "towctrans", - "strncmp", - "strtoul", - "fwrite", - "exit", - "swprintf", - "wcstok", "strftime", - "sprintf", - "wprintf", - "strpbrk", + "frexp", "time", - "rand", - "srand", + "ctime", + "wcstod", + "fwide", + "wcscmp", "wmemmove", - "tan", - "tolower", - "fwprintf", - "towlower", - "wcstombs", - "printf", - "fprintf", + "strtod", + "fmod", + "wcschr", + "wcsrchr", + "strcmp", + "wctype", + "toupper", + "towupper", "strchr", "strrchr", - "wmemcpy", - "fread", - "getwchar", - "putwchar", - "longjmp", - "memcpy", - "wcsxfrm", - "wcscspn", - "getc", - "putc", - "getwc", - "putwc", - "wcscpy", - "wcsncpy", - "wcslen", - "floor", - "setbuf", - "ungetc", - "rename", - "remove", - "gmtime", - "mktime", - "fgetc", - "fputc", - "fgetwc", - "fputwc", - "memcmp", - "iswctype", "wmemcmp", - "ispunct", - "mbstowcs", - "wcscmp", - "mbsrtowcs", - "setlocale", - "wcsncmp", - "wcstoul", - "strtol", - "wcsftime", + "iswctype", + "gmtime", + "difftime", + "btowc", "iswprint", - "wcspbrk", - "iswdigit", - "isprint", - "fclose", - "atof", - "islower", - "iswlower", - "ctime", + "iswxdigit", + "cosh", + "memcmp", "wmemchr", + "isupper", + "iswupper", + "iswdigit", "memchr", - "wctrans", - "strcat", - "getenv", - "strncat", - "iswxdigit", - "wcschr", - "wcsrchr", "isxdigit", + "wmemcpy", + "mbtowc", + "setbuf", + "mbstowcs", + "wcscpy", + "memmove", "vswprintf", - "raise", - "iswspace", - "vsprintf", - "vwprintf", - "vprintf", - "swscanf", - "sinh", - "tmpfile", - "asin", - "mblen", "acos", - "mbrlen", - "cosh", - "difftime", - "memmove", - "abs", - "tmpnam", - "vfwprintf", - "setvbuf", - "vfprintf", - "scanf", - "sscanf", - "wscanf", - "fwscanf", - "ftell", - "fflush", - "atexit", - "iswcntrl", - "iscntrl", "mbrtowc", "wcrtomb", - "fabs", - "wcstol", - "strcoll", - "atan2", - "tanh", - "atan", - "fscanf", - "clock", - "getchar", - "putchar", - "abort", - "clearerr", + "mbsrtowcs", + "atof", + "strcpy", + "setlocale", "wcscat", - "wcsncat", "isdigit", - "isgraph", - "iswgraph", - "btowc", + "log10", + "tolower", + "floor", + "towlower", + "strcat", + "log", + "mktime", + "wcstoul", + "fseek", + "memcpy", + "wcstok", + "strtoul", + "wcscspn", + "islower", "div", + "iswlower", + "atexit", + "strtok", + "setvbuf", + "strcspn", "isspace", - "atol", - "labs", - "ceil", - "mbtowc", - "wcscoll", - "wctob", + "iswspace", "asctime", - "iswalnum", - "isalnum", - "mbsinit", + "wctob", + "wcsncmp", "atoi", + "ldexp", + "strncmp", + "wcspbrk", "wctomb", + "swprintf", + "sprintf", + "strpbrk", + "abs", + "fabs", + "wcsncpy", + "ispunct", + "iswpunct", + "strncpy", + "iswgraph", + "isprint", + "isgraph", + "wcscoll", + "wcstol", + "vsprintf", + "strcoll", + "strtol", + "sscanf", + "clearerr", + "swscanf", + "sinh", + "wcsncat", + "getenv", + "ceil", + "clock", + "wctrans", + "strncat", "ldiv", - "signal", - "realloc", + "iswcntrl", + "wcsspn", + "iscntrl", + "sin", + "strspn", + "mbsinit", + "longjmp", + "rand", + "srand", + "labs", + "tanh", + "calloc", + "atol", "localtime", + "realloc", + "malloc", + "atan2", + "tan", + "wcslen", + "strlen", "iswalpha", "localeconv", + "asin", + "iswalnum", + "isalnum", "isalpha", - "malloc", - "calloc" + "mblen", + "mbrlen", + "atan", + "signal" }; static const short lookup[] = { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 0, 1, -1, 2, -1, -1, - -1, -1, -1, 3, -1, 4, -1, -1, - -1, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, 6, -1, -1, -1, 7, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, 9, 10, 11, -1, - -1, 12, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 13, -1, -1, 14, -1, - -1, -1, -1, 15, -1, 16, -1, 17, - 18, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, -1, -1, -1, 21, 22, - -1, 23, -1, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 25, -1, -1, - -1, -1, 26, 27, -1, -1, -1, -1, - -1, -1, -1, -1, 28, -1, 29, 30, - -1, 31, 32, 33, -1, -1, -1, -1, - 34, -1, 35, -1, 36, -1, -1, 37, - 38, -1, -1, -1, -1, -1, -1, 39, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 40, 41, 42, 43, -1, 44, - -1, -1, -1, 45, -1, -1, -1, -1, - -1, 46, 47, 48, -1, -1, -1, 49, - 50, -1, -1, 51, -1, -1, 52, 53, - -1, -1, -1, -1, -1, 54, 55, -1, - -1, 56, 57, -1, -1, 58, -1, -1, - 59, 60, 61, 62, -1, 63, -1, -1, - -1, -1, -1, -1, -1, -1, 64, 65, - 66, -1, -1, -1, -1, -1, 67, -1, - -1, -1, -1, 68, -1, -1, -1, -1, - -1, -1, -1, -1, 69, 70, 71, 72, - -1, 73, 74, -1, 75, 76, 77, 78, - 79, 80, 81, -1, 82, -1, 83, -1, - -1, 84, 85, 86, 87, 88, -1, 89, - -1, 90, -1, 91, -1, 92, -1, 93, - -1, -1, -1, -1, -1, 94, -1, -1, - -1, -1, -1, -1, 95, 96, -1, -1, - -1, -1, 97, -1, -1, -1, -1, -1, - -1, -1, 98, 99, 100, 101, 102, 103, - 104, 105, -1, -1, -1, -1, -1, 106, - -1, 107, 108, -1, 109, -1, 110, -1, - -1, -1, -1, -1, 111, 112, -1, 113, - -1, -1, -1, -1, -1, -1, -1, -1, - 114, -1, -1, 115, 116, -1, -1, 117, - -1, -1, 118, -1, 119, -1, 120, -1, - -1, 121, -1, 122, -1, -1, -1, 123, - -1, -1, -1, -1, -1, -1, -1, 124, - 125, -1, 126, -1, -1, 127, -1, 128, - 129, 130, -1, 131, 132, -1, 133, -1, - -1, -1, 134, -1, -1, -1, -1, 135, - 136, 137, 138, -1, -1, -1, -1, 139, - 140, 141, -1, 142, -1, 143, 144, 145, - -1, -1, 146, -1, 147, -1, -1, 148, - -1, 149, -1, -1, 150, -1, 151, -1, - -1, -1, 152, -1, -1, 153, -1, -1, - -1, 154, -1, -1, -1, 155, 156, 157, - 158, -1, 159, -1, 160, -1, -1, -1, - -1, -1, 161, 162, 163, -1, -1, -1, - -1, -1, -1, -719, -1, 166, 167, -43, - -2, 168, -1, 169, -1, -1, -1, 170, - -1, -1, -1, 171, -1, -1, 172, -1, - -1, 173, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 174, 175, -1, - -1, -1, -1, 176, -1, -1, -1, 177, - -1, -1, -1, -1, 178, -1, -1, 179, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 180, 181, -1, - 182, -1, -1, 183, -1, 184, 185, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 186, -1, -1, -1, -1, 187, - -1, -1, -1, -1, -1, -1, -1, -1, - 188, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 189, - 190, -1, -1, -1, -1, 191, -1, -1, - 192, -1, -1, -1, -1, -1, 193, -1, - -1, -1, -1, -1, 194, -1, -1, -1, - -1, -1, -1, -1, 195, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 196, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 197, -1, -1, -1, -1, -1, -1, - 198, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 199, -1, -1, -1, -1, -1, -1, - -1, 200, -1, -1, -1, -1, -1, 201, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 202, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 203, -1, - -1, -1, -1, -1, -1, 204, -1, -1, - 205, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 206 + -1, -1, -1, 0, 1, -1, -1, -1, + -1, -1, -1, 2, -1, -1, -1, -1, + -1, 3, -1, -1, 4, -1, 5, 6, + 7, -1, -1, -1, -1, 8, -1, -1, + -1, 9, 10, 11, -1, -1, 12, 13, + 14, -1, 15, -1, 16, 17, 18, 19, + -1, 20, 21, 22, 23, 24, -1, -1, + -1, -1, 25, -1, 26, 27, -1, 28, + 29, 30, -1, 31, 32, -1, 33, -1, + 34, 35, 36, -1, 37, -1, -1, 38, + 39, -1, -1, -1, 40, 41, -1, -1, + 42, 43, 44, 45, 46, 47, -1, 48, + 49, 50, 51, -1, 52, -1, -1, 53, + 54, 55, 56, 57, -1, 58, 59, -273, + 62, 63, -1, 64, -96, -2, 65, 66, + 67, -1, 68, -1, 69, 70, 71, -1, + 72, -1, -1, 73, -1, -1, -1, 74, + 75, 76, -1, 77, -1, -1, 78, -1, + -1, 79, 80, 81, 82, 83, 84, 85, + -1, -1, 86, 87, 88, -1, 89, 90, + -1, 91, -1, 92, -1, 93, -1, -1, + -1, 94, -1, -1, 95, -1, 96, -1, + -1, -1, -1, 97, 98, 99, -1, 100, + -1, 101, 102, 103, -1, -1, -1, -1, + -1, 104, -1, 105, 106, -1, -1, -1, + -1, -1, 107, -1, -1, -1, -1, 108, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 109, -1, -1, 110, -1, 111, -1, + -1, -1, -1, -1, 112, 113, -1, 114, + -1, 115, 116, 117, -1, 118, 119, 120, + -1, -1, 121, 122, -1, 123, -1, 124, + -1, -1, -1, -1, -1, -1, -1, 125, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 126, 127, -1, -1, -1, 128, 129, + -1, -1, -1, 130, 131, -1, -1, 132, + 133, 134, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 135, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 136, -1, -1, -1, 137, 138, -1, -1, + -1, -1, 139, -1, 140, -1, -1, -1, + -1, -1, -1, -1, -1, 141, -1, 142, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 143, 144, -1, -1, -1, -1, + -1, -1, -1, -1, 145, -1, -1, -1, + -1, -1, 146, -1, -1, -1, -1, -1, + -1, 147, 148, -1, -1, -1, -1, -1, + -1, 149, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 150, -1, -1, -1, -1, -1, + -1, -1, -1, 151, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 152, -1, + -1, -1, -1, -1, -1, -1, 153, -1, + -1, -1, -1, -1, -1, 154, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 155 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a1fa753fc4d2d3cfe6ceb39dd645fa7e0f240338..d9b15bd9768b4bbb627505ed9980e1c372793b95 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -665,7 +665,7 @@ in the following sections. @gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol -ffixed-@var{reg} -fexceptions @gol -fnon-call-exceptions -funwind-tables @gol --fasynchronous-unwind-tables -fforced-unwind-exceptions @gol +-fasynchronous-unwind-tables @gol -finhibit-size-directive -finstrument-functions @gol -fno-common -fno-ident -fno-gnu-linker @gol -fpcc-struct-return -fpic -fPIC @gol @@ -10849,13 +10849,6 @@ instructions to throw exceptions, i.e.@: memory references or floating point instructions. It does not allow exceptions to be thrown from arbitrary signal handlers such as @code{SIGALRM}. -@item -fforced-unwind-exceptions -@opindex fforced-unwind-exceptions -Generate code that checks for non-catchable exceptions derived from -@code{_Unwind_ForcedUnwind}, such as from @code{longjmp_unwind} or -from pthread cancellation. There is some amount of code-size -overhead associated with this, so it is not default. - @item -funwind-tables @opindex funwind-tables Similar to @option{-fexceptions}, except that it will just generate any needed diff --git a/gcc/except.c b/gcc/except.c index afc6a01f3dafe712a39e8a20de4a9ac83f0df9a4..3cd9b90d37dc72c9489b0a7efa012fff7f7d3d23 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -564,9 +564,7 @@ expand_eh_region_end_cleanup (handler) emit_label (region->label); - if (flag_non_call_exceptions - || flag_forced_unwind_exceptions - || region->may_contain_throw) + if (flag_non_call_exceptions || region->may_contain_throw) { /* Give the language a chance to specify an action to be taken if an exception is thrown that would propagate out of the HANDLER. */ @@ -1135,40 +1133,21 @@ convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur) } else if (INSN_P (insn)) { - rtx note; - switch (cur) + if (cur > 0 + && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX) + /* Calls can always potentially throw exceptions, unless + they have a REG_EH_REGION note with a value of 0 or less. + Which should be the only possible kind so far. */ + && (GET_CODE (insn) == CALL_INSN + /* If we wanted exceptions for non-call insns, then + any may_trap_p instruction could throw. */ + || (flag_non_call_exceptions + && GET_CODE (PATTERN (insn)) != CLOBBER + && GET_CODE (PATTERN (insn)) != USE + && may_trap_p (PATTERN (insn))))) { - default: - /* An existing region note may be present to suppress - exception handling. Anything with a note value of -1 - cannot throw an exception of any kind. A note value - of 0 means that "normal" exceptions are suppressed, - but not necessarily "forced unwind" exceptions. */ - note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - if (note) - { - if (flag_forced_unwind_exceptions - && INTVAL (XEXP (note, 0)) >= 0) - XEXP (note, 0) = GEN_INT (cur); - break; - } - - /* Calls can always potentially throw exceptions; if we wanted - exceptions for non-call insns, then any may_trap_p - instruction can throw. */ - if (GET_CODE (insn) != CALL_INSN - && (!flag_non_call_exceptions - || GET_CODE (PATTERN (insn)) == CLOBBER - || GET_CODE (PATTERN (insn)) == USE - || !may_trap_p (PATTERN (insn)))) - break; - - REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, - GEN_INT (cur), + REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur), REG_NOTES (insn)); - - case 0: - break; } if (GET_CODE (insn) == CALL_INSN @@ -1727,14 +1706,7 @@ build_post_landing_pads () for (c = region->u.try.catch; c ; c = c->u.catch.next_catch) { if (c->u.catch.type_list == NULL) - { - if (flag_forced_unwind_exceptions) - emit_cmp_and_jump_insns - (cfun->eh->filter, const0_rtx, GT, NULL_RTX, - word_mode, 0, c->label); - else - emit_jump (c->label); - } + emit_jump (c->label); else { /* Need for one cmp/jump per type caught. Each type @@ -1795,33 +1767,8 @@ build_post_landing_pads () break; case ERT_CLEANUP: - region->post_landing_pad = region->label; - break; - case ERT_MUST_NOT_THROW: - /* See maybe_remove_eh_handler about removing region->label. */ - if (flag_forced_unwind_exceptions && region->label) - { - region->post_landing_pad = gen_label_rtx (); - - start_sequence (); - - emit_label (region->post_landing_pad); - emit_cmp_and_jump_insns (cfun->eh->filter, const0_rtx, GT, - NULL_RTX, word_mode, 0, region->label); - - region->resume - = emit_jump_insn (gen_rtx_RESX (VOIDmode, - region->region_number)); - emit_barrier (); - - seq = get_insns (); - end_sequence (); - - emit_insn_before (seq, region->label); - } - else - region->post_landing_pad = region->label; + region->post_landing_pad = region->label; break; case ERT_CATCH: @@ -2001,21 +1948,6 @@ sjlj_find_directly_reachable_regions (lp_info) if (rc != RNL_NOT_CAUGHT) break; } - - /* Forced unwind exceptions aren't blocked. */ - if (flag_forced_unwind_exceptions && rc == RNL_BLOCKED) - { - struct eh_region *r; - for (r = region->outer; r ; r = r->outer) - if (r->type == ERT_CLEANUP) - { - rc = RNL_MAYBE_CAUGHT; - if (! region->label) - region = r; - break; - } - } - if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT) { lp_info[region->region_number].directly_reachable = 1; @@ -2854,21 +2786,7 @@ reachable_handlers (insn) while (region) { if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT) - { - /* Forced unwind exceptions are neither BLOCKED nor CAUGHT. - Make sure the cleanup regions are reachable. */ - if (flag_forced_unwind_exceptions) - { - while ((region = region->outer) != NULL) - if (region->type == ERT_CLEANUP) - { - add_reachable_handler (&info, region, region); - break; - } - } - break; - } - + break; /* If we have processed one cleanup, there is no point in processing any more of them. Each cleanup will have an edge to the next outer cleanup region, so the flow graph will be @@ -2990,10 +2908,6 @@ can_throw_external (insn) if (INTVAL (XEXP (note, 0)) <= 0) return false; - /* Forced unwind excptions are not catchable. */ - if (flag_forced_unwind_exceptions && GET_CODE (insn) == CALL_INSN) - return true; - region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; type_thrown = NULL_TREE; @@ -3348,26 +3262,12 @@ collect_one_action_chain (ar_hash, region) { if (c->u.catch.type_list == NULL) { - int filter; - - /* Forced exceptions run cleanups, always. Record them if - they exist. */ - next = 0; - if (flag_forced_unwind_exceptions) - { - struct eh_region *r; - for (r = c->outer; r ; r = r->outer) - if (r->type == ERT_CLEANUP) - { - next = add_action_record (ar_hash, 0, 0); - break; - } - } - /* Retrieve the filter from the head of the filter list where we have stored it (see assign_filter_values). */ - filter = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list)); - next = add_action_record (ar_hash, filter, next); + int filter + = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list)); + + next = add_action_record (ar_hash, filter, 0); } else { @@ -3412,13 +3312,6 @@ collect_one_action_chain (ar_hash, region) requires no call-site entry. Note that this differs from the no handler or cleanup case in that we do require an lsda to be generated. Return a magic -2 value to record this. */ - if (flag_forced_unwind_exceptions) - { - struct eh_region *r; - for (r = region->outer; r ; r = r->outer) - if (r->type == ERT_CLEANUP) - return 0; - } return -2; case ERT_CATCH: diff --git a/gcc/flags.h b/gcc/flags.h index 982cb9331590699d14dd774d187ad0e0118461b3..c58b5e6a39186376ae7d0e9e4c5a4b3093b5af8b 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -475,10 +475,6 @@ extern int flag_unwind_tables; extern int flag_asynchronous_unwind_tables; -/* Nonzero means allow for forced unwinding. */ - -extern int flag_forced_unwind_exceptions; - /* Nonzero means don't place uninitialized global data in common storage by default. */ diff --git a/gcc/libgcc-std.ver b/gcc/libgcc-std.ver index c8a1a8b83c9a843f3d9fd90f66fd80fd1ff9c207..eb477af0585087d1f8a6220b97880f2da75d8e81 100644 --- a/gcc/libgcc-std.ver +++ b/gcc/libgcc-std.ver @@ -181,6 +181,8 @@ GCC_3.3 { _Unwind_FindEnclosingFunction _Unwind_GetCFA _Unwind_Backtrace + _Unwind_Resume_or_Rethrow + _Unwind_SjLj_Resume_or_Rethrow } %inherit GCC_3.4 GCC_3.3 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9dff4e357458d05b8757fef8ea132d2f10c8ad28..a1bb392b6c6fa5d9acea3e1530ddcf49c4357bf1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2003-05-07 Richard Henderson <rth@redhat.com> + + PR c++/10570 + * g++.dg/eh/forced1.C: Expect catch-all handlers to run. + Verify exception_cleanup not called for rethrows. + * g++.dg/eh/forced2.C: Test that exception_cleanup is called + when exiting catch block without rethrowing. + * g++.dg/eh/forced3.C: New. + * g++.dg/eh/forced4.C: New. + 2003-05-07 Aldy Hernandez <aldyh@redhat.com> * gcc.dg/20030505.c: Fix triplet. diff --git a/gcc/testsuite/g++.dg/eh/forced1.C b/gcc/testsuite/g++.dg/eh/forced1.C index dc0d8b0084d90da247beb5f1da56532402d436fc..8f090fa9df5ea57f58c760b83ea92e0a1c277a7b 100644 --- a/gcc/testsuite/g++.dg/eh/forced1.C +++ b/gcc/testsuite/g++.dg/eh/forced1.C @@ -1,7 +1,7 @@ // { dg-do run } -// { dg-options "-fforced-unwind-exceptions" } -// Test that forced unwinding runs all cleanups, and only cleanups. +// Test that forced unwinding runs all cleanups. Also tests that +// rethrowing doesn't call the exception object destructor. #include <unwind.h> #include <stdlib.h> @@ -17,7 +17,7 @@ force_unwind_stop (int version, _Unwind_Action actions, { if (actions & _UA_END_OF_STACK) { - if (test != 5) + if (test != 15) abort (); exit (0); } @@ -25,18 +25,24 @@ force_unwind_stop (int version, _Unwind_Action actions, return _URC_NO_REASON; } +static void +force_unwind_cleanup (_Unwind_Reason_Code, struct _Unwind_Exception *) +{ + abort (); +} + static void force_unwind () { _Unwind_Exception *exc = new _Unwind_Exception; exc->exception_class = 0; - exc->exception_cleanup = 0; - + exc->exception_cleanup = force_unwind_cleanup; + #ifndef __USING_SJLJ_EXCEPTIONS__ _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); #else _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); #endif - + abort (); } @@ -58,18 +64,17 @@ static void doit () } catch(...) { test |= 2; + throw; } } catch(...) { test |= 8; + throw; } } int main() { - try { - doit (); - } catch (...) { - } + doit (); abort (); } diff --git a/gcc/testsuite/g++.dg/eh/forced2.C b/gcc/testsuite/g++.dg/eh/forced2.C index 4feb4fed985899f55f09629d5eb4e61a0845b2f5..ebfda5554f2ef0a6e12032c61636544cc2b3aa3a 100644 --- a/gcc/testsuite/g++.dg/eh/forced2.C +++ b/gcc/testsuite/g++.dg/eh/forced2.C @@ -1,13 +1,11 @@ // { dg-do run } -// { dg-options "-fforced-unwind-exceptions" } -// Test that forced unwinding runs all cleanups, and only cleanups. +// Test that leaving the catch block without rethrowing +// does call the exception object destructor. #include <unwind.h> #include <stdlib.h> -static int test = 0; - static _Unwind_Reason_Code force_unwind_stop (int version, _Unwind_Action actions, _Unwind_Exception_Class exc_class, @@ -16,24 +14,22 @@ force_unwind_stop (int version, _Unwind_Action actions, void *stop_parameter) { if (actions & _UA_END_OF_STACK) - { - if (test != 5) - abort (); - exit (0); - } - + abort (); return _URC_NO_REASON; } -// Note that neither the noreturn nor the nothrow specification -// affects forced unwinding. +static void +force_unwind_cleanup (_Unwind_Reason_Code, struct _Unwind_Exception *) +{ + exit (0); +} -static void __attribute__((noreturn)) -force_unwind () throw() +static void +force_unwind () { _Unwind_Exception *exc = new _Unwind_Exception; exc->exception_class = 0; - exc->exception_cleanup = 0; + exc->exception_cleanup = force_unwind_cleanup; #ifndef __USING_SJLJ_EXCEPTIONS__ _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); @@ -44,47 +40,10 @@ force_unwind () throw() abort (); } -struct S -{ - int bit; - S(int b) : bit(b) { } - ~S() { test |= bit; } -}; - -static void doit_3 () -{ - S one(1); - force_unwind (); -} - -static void doit_2 () -{ - try { - doit_3 (); - } catch (...) { - test |= 2; - } -} - -static void doit_1 () -{ - S four(4); - doit_2 (); -} - -static void doit () -{ - try { - doit_1 (); - } catch(...) { - test |= 8; - } -} - int main() { try { - doit (); + force_unwind (); } catch (...) { } abort (); diff --git a/gcc/testsuite/g++.dg/eh/forced3.C b/gcc/testsuite/g++.dg/eh/forced3.C new file mode 100644 index 0000000000000000000000000000000000000000..2de421c4412f209cdde98cc0aba13d80bcb941e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/forced3.C @@ -0,0 +1,55 @@ +// { dg-do run } + +// Test that forced unwinding calls std::unexpected going +// throw a nothrow function. + +#include <unwind.h> +#include <stdlib.h> +#include <exception> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void __attribute__((noreturn)) +force_unwind () +{ + _Unwind_Exception *exc = new _Unwind_Exception; + exc->exception_class = 0; + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +static void +handle_unexpected () +{ + exit (0); +} + +static void +doit () throw() +{ + force_unwind (); +} + +int main() +{ + std::set_unexpected (handle_unexpected); + doit (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/eh/forced4.C b/gcc/testsuite/g++.dg/eh/forced4.C new file mode 100644 index 0000000000000000000000000000000000000000..be03a7544b6282bc236e9cfa5761c8751413ef73 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/forced4.C @@ -0,0 +1,49 @@ +// { dg-do run } + +// Test that forced unwinding does not call std::unexpected going +// throw a function with a non-empty exception spec. + +#include <unwind.h> +#include <stdlib.h> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void __attribute__((noreturn)) +force_unwind () +{ + _Unwind_Exception *exc = new _Unwind_Exception; + exc->exception_class = 0; + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +static void +doit () throw(int) +{ + force_unwind (); +} + +int main() +{ + try { + doit (); + } catch (...) { + } +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 8dcc44c3e541d88c156e0c795640c085916828ee..bd44d2e7693e484f3d5d3a252cc90d870db44a67 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -740,10 +740,6 @@ int flag_unwind_tables = 0; int flag_asynchronous_unwind_tables = 0; -/* Nonzero means allow for forced unwinding. */ - -int flag_forced_unwind_exceptions; - /* Nonzero means don't place uninitialized global data in common storage by default. */ @@ -1128,8 +1124,6 @@ static const lang_independent_options f_options[] = N_("Generate unwind tables exact at each instruction boundary") }, {"non-call-exceptions", &flag_non_call_exceptions, 1, N_("Support synchronous non-call exceptions") }, - {"forced-unwind-exceptions", &flag_forced_unwind_exceptions, 1, - N_("Support forced unwinding, e.g. for thread cancellation") }, {"profile-arcs", &profile_arc_flag, 1, N_("Insert arc based program profiling code") }, {"test-coverage", &flag_test_coverage, 1, diff --git a/gcc/unwind-sjlj.c b/gcc/unwind-sjlj.c index 6d6fd8bc9b54878130b258461333c16a4573bc32..8d9766f5bc8cd87a9973324b74139376d4910542 100644 --- a/gcc/unwind-sjlj.c +++ b/gcc/unwind-sjlj.c @@ -285,6 +285,7 @@ uw_identify_context (struct _Unwind_Context *context) #define _Unwind_RaiseException _Unwind_SjLj_RaiseException #define _Unwind_ForcedUnwind _Unwind_SjLj_ForcedUnwind #define _Unwind_Resume _Unwind_SjLj_Resume +#define _Unwind_Resume_or_Rethrow _Unwind_SjLj_Resume_or_Rethrow #include "unwind.inc" diff --git a/gcc/unwind.h b/gcc/unwind.h index 8f7a499330e92c86f483675821dfb7d43512c760..a0d6ab3a14b02c6459c7f2017deb615847d68474 100644 --- a/gcc/unwind.h +++ b/gcc/unwind.h @@ -127,6 +127,10 @@ extern void _Unwind_DeleteException (struct _Unwind_Exception *); e.g. executing cleanup code, and not to implement rethrowing. */ extern void _Unwind_Resume (struct _Unwind_Exception *); +/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow + a normal exception that was handled. */ +extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + /* @@@ Use unwind data to perform a stack backtrace. The trace callback is called for every stack frame in the call chain, but no cleanup actions are performed. */ @@ -184,6 +188,7 @@ extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *); /* @@@ The following provide access to the base addresses for text and data-relative addressing in the LDSA. In order to stay link diff --git a/gcc/unwind.inc b/gcc/unwind.inc index 225b046d37f825173dce392ad94e6353eddea90b..0938d501f5fb53b0306f3601e4dcb9691b4778e2 100644 --- a/gcc/unwind.inc +++ b/gcc/unwind.inc @@ -232,12 +232,40 @@ _Unwind_Resume (struct _Unwind_Exception *exc) uw_install_context (&this_context, &cur_context); } + +/* Resume propagation of an FORCE_UNWIND exception, or to rethrow + a normal exception that was handled. */ + +_Unwind_Reason_Code +_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc) +{ + struct _Unwind_Context this_context, cur_context; + _Unwind_Reason_Code code; + + /* Choose between continuing to process _Unwind_RaiseException + or _Unwind_ForcedUnwind. */ + if (exc->private_1 == 0) + return _Unwind_RaiseException (exc); + + uw_init_context (&this_context); + cur_context = this_context; + + code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); + + if (code != _URC_INSTALL_CONTEXT) + abort (); + + uw_install_context (&this_context, &cur_context); +} + + /* A convenience function that calls the exception_cleanup field. */ void _Unwind_DeleteException (struct _Unwind_Exception *exc) { - (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc); + if (exc->exception_cleanup) + (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc); } @@ -274,4 +302,3 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument) return code; } - diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b79cdf2e00a971eb21d3a5d25ddeb32d662b24e9..b9c7bcb0a043a480ca7c8ccb98b2b881495af894 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2003-05-07 Richard Henderson <rth@redhat.com> + + PR c++/10570 + * libsupc++/eh_catch.cc (__cxa_begin_catch): Handle foreign exceptions. + (__cxa_end_catch): Likewise. + * libsupc++/eh_throw.cc (__cxa_rethrow): Likewise. Use + _Unwind_Resume_or_Rethrow. + * libsupc++/eh_personality.cc (empty_exception_spec): New. + (PERSONALITY_FUNCTION): Don't ignore terminate or catch-all + for _UA_FORCE_UNWIND. Honor empty filter spec for foreign + exceptions. Don't push terminate/unexpected to cxa functions. + (__cxa_call_unexpected): Remove foreign exception fixmes. + 2003-05-07 Benjamin Kosnik <bkoz@redhat.com> * testsuite/27_io/ios_base/cons: New. diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc index ba49dfe7e44d314d5a5abd10356352053279d2e0..4a678eb9fb24ea67acf8bf3763190250c545a1b3 100644 --- a/libstdc++-v3/libsupc++/eh_catch.cc +++ b/libstdc++-v3/libsupc++/eh_catch.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for catching. -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. // // This file is part of GNU CC. // @@ -39,15 +39,28 @@ __cxa_begin_catch (void *exc_obj_in) { _Unwind_Exception *exceptionObject = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); - - // ??? Foreign exceptions can't be stacked here, and there doesn't - // appear to be any place to store for __cxa_end_catch to destroy. - - __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); __cxa_eh_globals *globals = __cxa_get_globals (); __cxa_exception *prev = globals->caughtExceptions; - int count = header->handlerCount; + __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); + + // Foreign exceptions can't be stacked here. If the exception stack is + // empty, then fine. Otherwise we really have no choice but to terminate. + // Note that this use of "header" is a lie. It's fine so long as we only + // examine header->unwindHeader though. + if (header->unwindHeader.exception_class != __gxx_exception_class) + { + if (prev != 0) + std::terminate (); + + // Remember for end_catch and rethrow. + globals->caughtExceptions = header; + + // ??? No sensible value to return; we don't know what the + // object is, much less where it is in relation to the header. + return 0; + } + int count = header->handlerCount; if (count < 0) // This exception was rethrown from an immediately enclosing region. count = -count + 1; @@ -71,8 +84,22 @@ __cxa_end_catch () { __cxa_eh_globals *globals = __cxa_get_globals_fast (); __cxa_exception *header = globals->caughtExceptions; - int count = header->handlerCount; + // A rethrow of a foreign exception will be removed from the + // the exception stack immediately by __cxa_rethrow. + if (!header) + return; + + // A foreign exception couldn't have been stacked (see above), + // so by definition processing must be complete. + if (header->unwindHeader.exception_class != __gxx_exception_class) + { + globals->caughtExceptions = 0; + _Unwind_DeleteException (&header->unwindHeader); + return; + } + + int count = header->handlerCount; if (count < 0) { // This exception was rethrown. Decrement the (inverted) catch @@ -92,7 +119,7 @@ __cxa_end_catch () } else if (count < 0) // A bug in the exception handling library or compiler. - std::abort (); + std::terminate (); header->handlerCount = count; } diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index acc9c2eb63e1260a1284520d3d4c856e06eea11a..2b315c3956e24ada81fd41c4e1d8a772689e2eb4 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -1,5 +1,5 @@ // -*- C++ -*- The GNU C++ exception personality routine. -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of GNU CC. // @@ -124,6 +124,8 @@ get_adjusted_ptr (const std::type_info *catch_type, return false; } +// Return true if THROW_TYPE matches one if the filter types. + static bool check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, void *thrown_ptr, _Unwind_Sword filter_value) @@ -154,6 +156,18 @@ check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, } } +// Return true if the filter spec is empty, ie throw(). + +static bool +empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value) +{ + const unsigned char *e = info->TType - filter_value - 1; + _Unwind_Word tmp; + + e = read_uleb128 (e, &tmp); + return tmp == 0; +} + // Using a different personality function name causes link failures // when trying to mix code using different exception handling models. #ifdef _GLIBCPP_SJLJ_EXCEPTIONS @@ -197,6 +211,7 @@ PERSONALITY_FUNCTION (int version, && exception_class == __gxx_exception_class) { handler_switch_value = xh->handlerSwitchValue; + language_specific_data = xh->languageSpecificData; landing_pad = (_Unwind_Ptr) xh->catchTemp; found_type = (landing_pad == 0 ? found_terminate : found_handler); goto install_context; @@ -275,7 +290,7 @@ PERSONALITY_FUNCTION (int version, // If ip is not present in the table, call terminate. This is for // a destructor inside a cleanup, or a library routine the compiler // was not expecting to throw. - found_type = (actions & _UA_FORCE_UNWIND ? found_nothing : found_terminate); + found_type = found_terminate; goto do_something; found_something: @@ -327,23 +342,15 @@ PERSONALITY_FUNCTION (int version, // Positive filter values are handlers. catch_type = get_ttype_entry (&info, ar_filter); - // Null catch type is a catch-all handler. We can catch - // foreign exceptions with this. - if (! catch_type) - { - if (!(actions & _UA_FORCE_UNWIND)) - { - saw_handler = true; - break; - } - } - else if (throw_type) + // Null catch type is a catch-all handler; we can catch foreign + // exceptions with this. Otherwise we must match types. + if (! catch_type + || (throw_type + && get_adjusted_ptr (catch_type, throw_type, + &thrown_ptr))) { - if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr)) - { - saw_handler = true; - break; - } + saw_handler = true; + break; } } else @@ -352,9 +359,12 @@ PERSONALITY_FUNCTION (int version, // ??? How do foreign exceptions fit in? As far as I can // see we can't match because there's no __cxa_exception // object to stuff bits in for __cxa_call_unexpected to use. + // Allow them iff the exception spec is non-empty. I.e. + // a throw() specification results in __unexpected. if (throw_type - && ! check_exception_spec (&info, throw_type, thrown_ptr, - ar_filter)) + ? ! check_exception_spec (&info, throw_type, thrown_ptr, + ar_filter) + : empty_exception_spec (&info, ar_filter)) { saw_handler = true; break; @@ -400,19 +410,37 @@ PERSONALITY_FUNCTION (int version, } install_context: - if (found_type == found_terminate) + // We can't use any of the cxa routines with foreign exceptions, + // because they all expect ue_header to be a struct __cxa_exception. + // So in that case, call terminate or unexpected directly. + if ((actions & _UA_FORCE_UNWIND) + || exception_class != __gxx_exception_class) { - __cxa_begin_catch (&xh->unwindHeader); - __terminate (xh->terminateHandler); + if (found_type == found_terminate) + std::terminate (); + else if (handler_switch_value < 0) + { + try + { std::unexpected (); } + catch(...) + { std::terminate (); } + } } - - // Cache the TType base value for __cxa_call_unexpected, as we won't - // have an _Unwind_Context then. - if (handler_switch_value < 0) + else { - parse_lsda_header (context, xh->languageSpecificData, &info); - xh->catchTemp = base_of_encoded_value (info.ttype_encoding, - context); + if (found_type == found_terminate) + { + __cxa_begin_catch (&xh->unwindHeader); + __terminate (xh->terminateHandler); + } + + // Cache the TType base value for __cxa_call_unexpected, as we won't + // have an _Unwind_Context then. + if (handler_switch_value < 0) + { + parse_lsda_header (context, language_specific_data, &info); + xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context); + } } _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), @@ -457,20 +485,19 @@ __cxa_call_unexpected (void *exc_obj_in) catch(...) { // Get the exception thrown from unexpected. - // ??? Foreign exceptions can't be stacked this way. - + __cxa_eh_globals *globals = __cxa_get_globals_fast (); __cxa_exception *new_xh = globals->caughtExceptions; void *new_ptr = new_xh + 1; - + // We don't quite have enough stuff cached; re-parse the LSDA. parse_lsda_header (0, xh_lsda, &info); - + // If this new exception meets the exception spec, allow it. if (check_exception_spec (&info, new_xh->exceptionType, new_ptr, xh_switch_value)) __throw_exception_again; - + // If the exception spec allows std::bad_exception, throw that. // We don't have a thrown object to compare against, but since // bad_exception doesn't have virtual bases, that's OK; just pass 0. @@ -479,6 +506,7 @@ __cxa_call_unexpected (void *exc_obj_in) if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value)) throw std::bad_exception(); #endif + // Otherwise, die. __terminate (xh_terminate_handler); } diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index f20368a13f6cc811a2bd0c435516120807d642c1..4fe4cd3a9760f55957d121683150b5913ef70d1a 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for throwing. -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. // // This file is part of GNU CC. // @@ -90,12 +90,15 @@ __cxa_rethrow () if (header) { // Tell __cxa_end_catch this is a rethrow. - header->handlerCount = -header->handlerCount; + if (header->unwindHeader.exception_class != __gxx_exception_class) + globals->caughtExceptions = 0; + else + header->handlerCount = -header->handlerCount; #ifdef _GLIBCPP_SJLJ_EXCEPTIONS - _Unwind_SjLj_RaiseException (&header->unwindHeader); + _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); #else - _Unwind_RaiseException (&header->unwindHeader); + _Unwind_Resume_or_Rethrow (&header->unwindHeader); #endif // Some sort of unwinding error. Note that terminate is a handler.