This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[3.3] Followup to C++ forced unwinding


The result of the original thread

    http://gcc.gnu.org/ml/gcc-patches/2003-04/msg00008.html

endorsed different semantics than I assumed in my original
patch.  Here I update things to match the consensus.

Mark, I know it's getting late, but is this ok for 3.3?
(There'll be a pr shortly; wanted to include a pointer to
this message in the description text though.)


r~


gcc/
	* except.c (RNL_ALWAYS_CAUGHT): New.
	(expand_eh_region_end_cleanup): Ignore flag_forced_unwind_exceptions.
	(convert_from_eh_region_ranges_1): Likewise.
	(build_post_landing_pads): Likewise.
	(sjlj_find_directly_reachable_regions): Likewise.
	(collect_one_action_chain): Likewise.
	(reachable_next_level): Return RNL_ALWAYS_CAUGHT for empty filter
	spec and must_not_throw shadowing other catch handlers.
	(reachable_handlers): With forced unwinding, only mark cleanups
	live after catch(...), not throw().
	(can_throw_external): Similarly wrt exceptions escaping the function.

gcc/cp/
	* Make-lang.in (cfns.h): Add -t to gperf invocation.
	* cfns.gperf: Use a structure; mark POSIX cancellation points.
	* except.c (nothrow_libfn_p): Return bool; return false for 
	cancellation points when forced unwinding in effect.
	* cp-tree.h (nothrow_libfn_p): Update declaration.

gcc/testsuite/
	* g++.dg/eh/forced2.C (force_unwind): Remove nothrow spec.

libstdc++-v3/
	* libsupc++/eh_personality.cc (empty_exception_spec): New.
	(PERSONALITY_FUNCTION): Ignore FORCE_UNWIND when considering
	must_not_throw barriers; allow empty filter specs to signal
	unexpected on FORCE and foreign exception types.

Index: gcc/except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.233.2.4
diff -c -p -d -u -r1.233.2.4 except.c
--- gcc/except.c	22 Apr 2003 15:50:54 -0000	1.233.2.4
+++ gcc/except.c	30 Apr 2003 17:34:44 -0000
@@ -1,6 +1,6 @@
 /* Implements exception handling.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Mike Stump <mrs@cygnus.com>.
 
 This file is part of GCC.
@@ -324,8 +324,12 @@ enum reachable_code
   RNL_NOT_CAUGHT,
   /* The given exception may need processing by the given region.  */
   RNL_MAYBE_CAUGHT,
-  /* The given exception is completely processed by the given region.  */
+  /* The given exception is completely processed by the given region,
+     via catch clauses.  */
   RNL_CAUGHT,
+  /* The given exception is completely processed by the given region, 
+     via empty eh filter specs or must_not_throw clauses.  */
+  RNL_ALWAYS_CAUGHT,
   /* The given exception is completely processed by the runtime.  */
   RNL_BLOCKED
 };
@@ -562,9 +566,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.  */
@@ -1140,16 +1142,10 @@ convert_from_eh_region_ranges_1 (pinsns,
 	      /* 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.  */
+		 of 0 means that "normal" exceptions are suppressed.  */
 	      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;
-		}
+		break;
 
 	      /* Calls can always potentially throw exceptions; if we wanted
 		 exceptions for non-call insns, then any may_trap_p
@@ -1793,33 +1789,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:
@@ -2000,21 +1971,7 @@ sjlj_find_directly_reachable_regions (lp
 	    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)
+      if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT || rc == RNL_ALWAYS_CAUGHT)
 	{
 	  lp_info[region->region_number].directly_reachable = 1;
 	  found_one = true;
@@ -2752,7 +2709,7 @@ reachable_next_level (region, type_throw
       if (region->u.allowed.type_list == NULL_TREE)
 	{
 	  add_reachable_handler (info, region, region);
-	  return RNL_CAUGHT;
+	  return RNL_ALWAYS_CAUGHT;
 	}
 
       /* Collect a list of lists of allowed types for use in detecting
@@ -2791,7 +2748,7 @@ reachable_next_level (region, type_throw
       if (info && info->handlers)
 	{
 	  add_reachable_handler (info, region, region);
-	  return RNL_CAUGHT;
+	  return RNL_ALWAYS_CAUGHT;
 	}
       else
 	return RNL_BLOCKED;
@@ -2851,10 +2808,11 @@ reachable_handlers (insn)
 
   while (region)
     {
-      if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
+      /* Forced unwind exceptions may be BLOCKED but not CAUGHT.
+	 Make sure the cleanup regions are reachable.  */
+      switch (reachable_next_level (region, type_thrown, &info))
 	{
-	  /* Forced unwind exceptions are neither BLOCKED nor CAUGHT.
-	     Make sure the cleanup regions are reachable.  */
+	case RNL_CAUGHT:
 	  if (flag_forced_unwind_exceptions)
 	    {
 	      while ((region = region->outer) != NULL)
@@ -2864,6 +2822,13 @@ reachable_handlers (insn)
 		    break;
 		  }
 	    }
+	  goto fini;
+
+	case RNL_ALWAYS_CAUGHT:
+	case RNL_BLOCKED:
+	  goto fini;
+
+	default:
 	  break;
 	}
 
@@ -2876,6 +2841,7 @@ reachable_handlers (insn)
       else
 	region = region->outer;
     }
+ fini:
     
   return info.handlers;
 }
@@ -2988,10 +2954,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;
@@ -3004,8 +2966,18 @@ can_throw_external (insn)
   /* If the exception is caught or blocked by any containing region,
      then it is not seen by any calling function.  */
   for (; region ; region = region->outer)
-    if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
-      return false;
+    switch (reachable_next_level (region, type_thrown, NULL))
+      {
+      case RNL_CAUGHT:
+	if (!flag_forced_unwind_exceptions)
+	  break;
+	/* FALLTHRU */
+      case RNL_ALWAYS_CAUGHT:
+      case RNL_BLOCKED:
+	return false;
+      default:
+	break;
+      }
 
   return true;
 }
@@ -3410,13 +3382,6 @@ collect_one_action_chain (ar_hash, regio
 	 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:
Index: gcc/cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.125.4.3
diff -c -p -d -u -r1.125.4.3 Make-lang.in
--- gcc/cp/Make-lang.in	13 Feb 2003 07:17:09 -0000	1.125.4.3
+++ gcc/cp/Make-lang.in	30 Apr 2003 17:34:45 -0000
@@ -98,7 +98,7 @@ cc1plus$(exeext): $(CXX_OBJS) $(CXX_C_OB
 
 # Special build rules.
 $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
-	gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' \
+	gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' -t \
 		$(srcdir)/cp/cfns.gperf > $(srcdir)/cp/cfns.h
 
 $(srcdir)/cp/parse.h: $(srcdir)/cp/parse.c
Index: gcc/cp/cfns.gperf
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cfns.gperf,v
retrieving revision 1.2
diff -c -p -d -u -r1.2 cfns.gperf
--- gcc/cp/cfns.gperf	4 Apr 2000 20:46:23 -0000	1.2
+++ gcc/cp/cfns.gperf	30 Apr 2003 17:34:45 -0000
@@ -1,4 +1,20 @@
 %{
+/* 
+ * The standard C library functions, for feeding to gperf; the result is used
+ * by nothrow_libfn_p.
+ *
+ *   [lib.res.on.exception.handling]: None of the functions from the
+ *   Standard C library shall report an error by throwing an
+ *   exception, unless it calls a program-supplied function that
+ *   throws an exception.
+ *
+ * bsearch and qsort are omitted because they can call such functions.
+ *
+ * Cancellation points are marked either 1 (primary cancellation point)
+ * or 2 (secondary cancellation point).  Taken from Section 2.9.5.2 of
+ * IEEE 1003.1 (POSIX 1) TC1.
+ */
+
 #ifdef __GNUC__
 __inline
 #endif
@@ -6,224 +22,215 @@ static unsigned int hash PARAMS ((const 
 #ifdef __GNUC__
 __inline
 #endif
-const char * libc_name_p PARAMS ((const char *, unsigned int));
+const struct libc_name_data *libc_name_p PARAMS ((const char *, unsigned int));
 %}
-# The standard C library functions, for feeding to gperf; the result is used
-# by nothrow_libfn_p.
-#
-#   [lib.res.on.exception.handling]: None of the functions from the
-#   Standard C library shall report an error by throwing an
-#   exception, unless it calls a program-supplied function that
-#   throws an exception.
-#
-# bsearch and qsort are commented out because they can call such functions.
-#
-abort
-abs
-acos
-asctime
-asin
-atan
-atan2
-atexit
-atof
-atoi
-atol
-#bsearch
-btowc
-calloc
-ceil
-clearerr
-clock
-cos
-cosh
-ctime
-difftime
-div
-exit
-exp
-fabs
-fclose
-feof
-ferror
-fflush
-fgetc
-fgetpos
-fgets
-fgetwc
-fgetws
-floor
-fmod
-fopen
-fprintf
-fputc
-fputs
-fputwc
-fputws
-fread
-free
-freopen
-frexp
-fscanf
-fseek
-fsetpos
-ftell
-fwide
-fwprintf
-fwrite
-fwscanf
-getc
-getchar
-getenv
-gets
-getwc
-getwchar
-gmtime
-isalnum
-isalpha
-iscntrl
-isdigit
-isgraph
-islower
-isprint
-ispunct
-isspace
-isupper
-iswalnum
-iswalpha
-iswcntrl
-iswctype
-iswdigit
-iswgraph
-iswlower
-iswprint
-iswpunct
-iswspace
-iswupper
-iswxdigit
-isxdigit
-labs
-ldexp
-ldiv
-localeconv
-localtime
-log
-log10
-longjmp
-malloc
-mblen
-mbrlen
-mbrtowc
-mbsinit
-mbsrtowcs
-mbstowcs
-mbtowc
-memchr
-memcmp
-memcpy
-memmove
-memset
-mktime
-modf
-perror
-pow
-printf
-putc
-putchar
-puts
-putwc
-putwchar
-#qsort
-raise
-rand
-realloc
-remove
-rename
-rewind
-scanf
-setbuf
-setlocale
-setvbuf
-signal
-sin
-sinh
-sprintf
-sqrt
-srand
-sscanf
-strcat
-strchr
-strcmp
-strcoll
-strcpy
-strcspn
-strerror
-strftime
-strlen
-strncat
-strncmp
-strncpy
-strpbrk
-strrchr
-strspn
-strstr
-strtod
-strtok
-strtol
-strtoul
-strxfrm
-swprintf
-swscanf
-system
-tan
-tanh
-time
-tmpfile
-tmpnam
-tolower
-toupper
-towctrans
-towlower
-towupper
-ungetc
-ungetwc
-vfprintf
-vfwprintf
-vprintf
-vsprintf
-vswprintf
-vwprintf
-wcrtomb
-wcscat
-wcschr
-wcscmp
-wcscoll
-wcscpy
-wcscspn
-wcsftime
-wcslen
-wcsncat
-wcsncmp
-wcsncpy
-wcspbrk
-wcsrchr
-wcsrtombs
-wcsspn
-wcsstr
-wcstod
-wcstok
-wcstol
-wcstombs
-wcstoul
-wcsxfrm
-wctob
-wctomb
-wctrans
-wctype
-wmemchr
-wmemcmp
-wmemcpy
-wmemmove
-wmemset
-wprintf
-wscanf
+struct libc_name_data { const char *name; int cancelation_point; };
+%%
+abort, 0
+abs, 0
+acos, 0
+asctime, 0
+asin, 0
+atan, 0
+atan2, 0
+atexit, 0
+atof, 0
+atoi, 0
+atol, 0
+btowc, 0
+calloc, 0
+ceil, 0
+clearerr, 0
+clock, 0
+cos, 0
+cosh, 0
+ctime, 0
+difftime, 0
+div, 0
+exit, 0
+exp, 0
+fabs, 0
+fclose, 2
+feof, 0
+ferror, 0
+fflush, 2
+fgetc, 2
+fgetpos, 2
+fgets, 2
+fgetwc, 2
+fgetws, 2
+floor, 0
+fmod, 0
+fopen, 2
+fprintf, 2
+fputc, 2
+fputs, 2
+fputwc, 2
+fputws, 2
+fread, 2
+free, 0
+freopen, 2
+frexp, 0
+fscanf, 2
+fseek, 2
+fsetpos, 2
+ftell, 2
+fwide, 0
+fwprintf, 2
+fwrite, 2
+fwscanf, 2
+getc, 2
+getchar, 2
+getenv, 0
+gets, 2
+getwc, 2
+getwchar, 2
+gmtime, 0
+isalnum, 0
+isalpha, 0
+iscntrl, 0
+isdigit, 0
+isgraph, 0
+islower, 0
+isprint, 0
+ispunct, 0
+isspace, 0
+isupper, 0
+iswalnum, 0
+iswalpha, 0
+iswcntrl, 0
+iswctype, 0
+iswdigit, 0
+iswgraph, 0
+iswlower, 0
+iswprint, 0
+iswpunct, 0
+iswspace, 0
+iswupper, 0
+iswxdigit, 0
+isxdigit, 0
+labs, 0
+ldexp, 0
+ldiv, 0
+localeconv, 0
+localtime, 0
+log, 0
+log10, 0
+longjmp, 0
+malloc, 0
+mblen, 0
+mbrlen, 0
+mbrtowc, 0
+mbsinit, 0
+mbsrtowcs, 0
+mbstowcs, 0
+mbtowc, 0
+memchr, 0
+memcmp, 0
+memcpy, 0
+memmove, 0
+memset, 0
+mktime, 0
+modf, 0
+perror, 2
+pow, 0
+printf, 2
+putc, 2
+putchar, 2
+puts, 2
+putwc, 2
+putwchar, 2
+raise, 0
+rand, 0
+realloc, 0
+remove, 2
+rename, 2
+rewind, 2
+scanf, 2
+setbuf, 0
+setlocale, 0
+setvbuf, 0
+signal, 0
+sin, 0
+sinh, 0
+sprintf, 2
+sqrt, 0
+srand, 0
+sscanf, 0
+strcat, 0
+strchr, 0
+strcmp, 0
+strcoll, 0
+strcpy, 0
+strcspn, 0
+strerror, 2
+strftime, 0
+strlen, 0
+strncat, 0
+strncmp, 0
+strncpy, 0
+strpbrk, 0
+strrchr, 0
+strspn, 0
+strstr, 0
+strtod, 0
+strtok, 0
+strtol, 0
+strtoul, 0
+strxfrm, 0
+swprintf, 0
+swscanf, 0
+system, 1
+tan, 0
+tanh, 0
+time, 0
+tmpfile, 2
+tmpnam, 2
+tolower, 0
+toupper, 0
+towctrans, 0
+towlower, 0
+towupper, 0
+ungetc, 2
+ungetwc, 2
+vfprintf, 2
+vfwprintf, 2
+vprintf, 2
+vsprintf, 0
+vswprintf, 0
+vwprintf, 2
+wcrtomb, 0
+wcscat, 0
+wcschr, 0
+wcscmp, 0
+wcscoll, 0
+wcscpy, 0
+wcscspn, 0
+wcsftime, 0
+wcslen, 0
+wcsncat, 0
+wcsncmp, 0
+wcsncpy, 0
+wcspbrk, 0
+wcsrchr, 0
+wcsrtombs, 0
+wcsspn, 0
+wcsstr, 0
+wcstod, 0
+wcstok, 0
+wcstol, 0
+wcstombs, 0
+wcstoul, 0
+wcsxfrm, 0
+wctob, 0
+wctomb, 0
+wctrans, 0
+wctype, 0
+wmemchr, 0
+wmemcmp, 0
+wmemcpy, 0
+wmemmove, 0
+wmemset, 0
+wprintf, 2
+wscanf, 2
+%%
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.776.2.18
diff -c -p -d -u -r1.776.2.18 cp-tree.h
--- gcc/cp/cp-tree.h	29 Apr 2003 18:51:55 -0000	1.776.2.18
+++ gcc/cp/cp-tree.h	30 Apr 2003 17:34:46 -0000
@@ -3910,7 +3910,7 @@ extern void expand_exception_blocks		PAR
 extern tree build_exc_ptr			PARAMS ((void));
 extern tree build_throw				PARAMS ((tree));
 extern void mark_all_runtime_matches            PARAMS ((void));
-extern int nothrow_libfn_p			PARAMS ((tree));
+extern bool nothrow_libfn_p			PARAMS ((tree));
 extern void check_handlers			PARAMS ((tree));
 extern void choose_personality_routine		PARAMS ((enum languages));
 
Index: gcc/cp/except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/except.c,v
retrieving revision 1.149
diff -c -p -d -u -r1.149 except.c
--- gcc/cp/except.c	4 Dec 2002 20:13:01 -0000	1.149
+++ gcc/cp/except.c	30 Apr 2003 17:34:47 -0000
@@ -870,10 +870,11 @@ is_admissible_throw_operand (expr)
 
 #include "cfns.h"
 
-int
+bool
 nothrow_libfn_p (fn)
      tree fn;
 {
+  const struct libc_name_data *entry;
   tree id;
 
   if (TREE_PUBLIC (fn)
@@ -883,10 +884,16 @@ nothrow_libfn_p (fn)
     /* OK */;
   else
     /* Can't be a C library function.  */
-    return 0;
+    return false;
 
   id = DECL_ASSEMBLER_NAME (fn);
-  return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
+  entry = libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
+  if (!entry)
+    return false;
+  if (flag_forced_unwind_exceptions)
+    return !entry->cancelation_point;
+  else
+    return true;
 }
 
 /* Returns nonzero if an exception of type FROM will be caught by a
Index: gcc/testsuite/g++.dg/eh/forced2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/eh/forced2.C,v
retrieving revision 1.1.2.1
diff -c -p -d -u -r1.1.2.1 forced2.C
--- gcc/testsuite/g++.dg/eh/forced2.C	2 Apr 2003 07:14:29 -0000	1.1.2.1
+++ gcc/testsuite/g++.dg/eh/forced2.C	30 Apr 2003 17:34:47 -0000
@@ -25,11 +25,10 @@ force_unwind_stop (int version, _Unwind_
   return _URC_NO_REASON;
 }
 
-// Note that neither the noreturn nor the nothrow specification
-// affects forced unwinding.
+// Note that the noreturn specification doesn't affect forced unwinding.
 
 static void __attribute__((noreturn))
-force_unwind () throw()
+force_unwind ()
 {
   _Unwind_Exception *exc = new _Unwind_Exception;
   exc->exception_class = 0;
Index: libstdc++-v3/libsupc++/eh_personality.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/eh_personality.cc,v
retrieving revision 1.10
diff -c -p -d -u -r1.10 eh_personality.cc
--- libstdc++-v3/libsupc++/eh_personality.cc	15 Aug 2002 18:05:41 -0000	1.10
+++ libstdc++-v3/libsupc++/eh_personality.cc	30 Apr 2003 17:34:49 -0000
@@ -124,6 +124,8 @@ get_adjusted_ptr (const std::type_info *
   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 *
     }
 }
 
+// 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
@@ -275,7 +289,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:
@@ -352,9 +366,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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]