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]

Yet another block_may_fallthru tweak (PR middle-end/19583)


A new test case in PR middle-end/19583 showed me that I wasn't
handling TRY_CATCH_EXPR with EH_FILTER_EXPR quite right in
block_may_fallthru.  A TRY_CATCH_EXPR with an EH_FILTER_EXPR is used
to only permit certain exceptions.  It handles a throw(TYPE)
expression in C++, in which the programmer has declared that any
exception other than TYPE should cause an unhandled exception error.

The semantics of TRY_CATCH_EXPR with EH_FILTER_EXPR is that the try
block is executed.  If it does not throw an exception, nothing special
happens.  If it does throw an exception, the exception is compared
against the EH_FILTER_TYPES field.  If it matches, the exception
continues unwinding.  If it does not match, the EH_FILTER_FAILURE
instructions are executed.

In terms of block_may_fallthru, what this means is that the value of
EH_FILTER_TYPES is unimportant.  If the exception matches
EH_FILTER_TYPES, then it continues unwinding, and the TRY_CATCH_EXPR
does not fall through.  If the exception does not match
EH_FILTER_TYPES, then the EH_FILTER_FAILURE code is executed, and we
can test whether that falls through.

This patch adjusts try_catch_may_fallthru to my new understanding.  It
causes no testsuite changes on i686-pc-linux-gnu.  I am running a
bootstrap now.  OK to commit the patch if the bootstrap succeeds?

I have included a new test case, which fails without this patch and
succeeds with it.

Ian


2005-02-08  Ian Lance Taylor  <ian@airs.com>

	PR middle-end/19583
	* gimple-low.c (try_catch_may_fallthru): In EH_FILTER_EXPR case,
	just check whether EH_FILTER_FAILURE falls through.


2005-02-08  Ian Lance Taylor  <ian@airs.com>

	PR middle-end/19583
	* g++.dg/warn/Wreturn-type-3.C: New test.


Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimple-low.c,v
retrieving revision 2.21
diff -p -u -r2.21 gimple-low.c
--- gimple-low.c	28 Jan 2005 17:32:57 -0000	2.21
+++ gimple-low.c	9 Feb 2005 03:33:28 -0000
@@ -291,15 +291,16 @@ try_catch_may_fallthru (tree stmt)
       return false;
 
     case EH_FILTER_EXPR:
-      /* If the exception does not match EH_FILTER_TYPES, we will
-	 execute EH_FILTER_FAILURE, and we will fall through if that
-	 falls through.  If the exception does match EH_FILTER_TYPES,
-	 we will fall through.  We don't know which exceptions may be
-	 generated, so we just check for EH_FILTER_TYPES being NULL,
-	 in which case we know that that the exception does not
-	 match.  */
-      return (EH_FILTER_TYPES (tsi_stmt (i)) != NULL
-	      || block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i))));
+      /* The exception filter expression only matters if there is an
+	 exception.  If the exception does not match EH_FILTER_TYPES,
+	 we will execute EH_FILTER_FAILURE, and we will fall through
+	 if that falls through.  If the exception does match
+	 EH_FILTER_TYPES, the stack unwinder will continue up the
+	 stack, so we will not fall through.  We don't know whether we
+	 will throw an exception which matches EH_FILTER_TYPES or not,
+	 so we just ignore EH_FILTER_TYPES and assume that we might
+	 throw an exception which doesn't match.  */
+      return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i)));
 
     default:
       /* This case represents statements to be executed when an


// PR middle-end/19583
// { dg-options "-Wreturn-type -O" }

struct E{};

inline int bar() throw(E)
{
  return 0;
}

void foo ()
{
  bar();
}


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