OSDN Git Service

PR target/23832
[pf3gnuchains/gcc-fork.git] / gcc / gimple-low.c
index 5165a9a..5c7c27f 100644 (file)
@@ -16,8 +16,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -25,7 +25,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm.h"
 #include "tree.h"
 #include "rtl.h"
-#include "errors.h"
 #include "varray.h"
 #include "tree-gimple.h"
 #include "tree-inline.h"
@@ -145,7 +144,7 @@ struct tree_opt_pass pass_lower_cf =
    when they are changed -- if this has to be done, the lowering routine must
    do it explicitly.  DATA is passed through the recursion.  */
 
-void
+static void
 lower_stmt_body (tree expr, struct lower_data *data)
 {
   tree_stmt_iterator tsi;
@@ -291,15 +290,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
@@ -348,7 +348,15 @@ block_may_fallthru (tree block)
       return try_catch_may_fallthru (stmt);
 
     case TRY_FINALLY_EXPR:
-      return block_may_fallthru (TREE_OPERAND (stmt, 1));
+      /* The finally clause is always executed after the try clause,
+        so if it does not fall through, then the try-finally will not
+        fall through.  Otherwise, if the try clause does not fall
+        through, then when the finally clause falls through it will
+        resume execution wherever the try clause was going.  So the
+        whole try-finally will only fall through if both the try
+        clause and the finally clause fall through.  */
+      return (block_may_fallthru (TREE_OPERAND (stmt, 0))
+             && block_may_fallthru (TREE_OPERAND (stmt, 1)));
 
     case MODIFY_EXPR:
       if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
@@ -360,6 +368,9 @@ block_may_fallthru (tree block)
     case CALL_EXPR:
       /* Functions that do not return do not fall through.  */
       return (call_expr_flags (stmt) & ECF_NORETURN) == 0;
+    
+    case CLEANUP_POINT_EXPR:
+      return block_may_fallthru (TREE_OPERAND (stmt, 0));
 
     default:
       return true;
@@ -508,11 +519,13 @@ record_vars (tree vars)
     {
       tree var = vars;
 
+      /* BIND_EXPRs contains also function/type/constant declarations
+         we don't need to care about.  */
+      if (TREE_CODE (var) != VAR_DECL)
+       continue;
       /* Nothing to do in this case.  */
       if (DECL_EXTERNAL (var))
        continue;
-      if (TREE_CODE (var) == FUNCTION_DECL)
-       continue;
 
       /* Record the variable.  */
       cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,