cp-gimplify.c (cp_genericize_r): Turn most of the function into a switch (TREE_CODE...
authorJakub Jelinek <jakub@redhat.com>
Wed, 14 Jun 2017 11:24:48 +0000 (13:24 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 14 Jun 2017 11:24:48 +0000 (13:24 +0200)
* cp-gimplify.c (cp_genericize_r): Turn most of the function
into a switch (TREE_CODE (stmt)) statement from long else if
sequence.

From-SVN: r249191

gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c

index ca0f9b200149f97c7d474d6a6e43a10e4f0944b1..b933392d58391e5afe18be6ac1b905a828c8cb03 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-14  Jakub Jelinek  <jakub@redhat.com>
+
+       * cp-gimplify.c (cp_genericize_r): Turn most of the function
+       into a switch (TREE_CODE (stmt)) statement from long else if
+       sequence.
+
 2017-06-13  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/80973
index a0abd51440da45c3ffbf83438fc65a2356ac157a..f010f6c63be10fbf08bda6a56ef83dbda72a3413 100644 (file)
@@ -1118,132 +1118,135 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       return NULL_TREE;
     }
 
-  if (TREE_CODE (stmt) == ADDR_EXPR
-      && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+  switch (TREE_CODE (stmt))
     {
-      /* If in an OpenMP context, note var uses.  */
-      if (__builtin_expect (wtd->omp_ctx != NULL, 0)
-         && omp_var_to_track (TREE_OPERAND (stmt, 0)))
-       omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
-      *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
-      *walk_subtrees = 0;
-    }
-  else if (TREE_CODE (stmt) == RETURN_EXPR
-          && TREE_OPERAND (stmt, 0)
-          && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
-    /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
-    *walk_subtrees = 0;
-  else if (TREE_CODE (stmt) == OMP_CLAUSE)
-    switch (OMP_CLAUSE_CODE (stmt))
-      {
-      case OMP_CLAUSE_LASTPRIVATE:
-       /* Don't dereference an invisiref in OpenMP clauses.  */
-       if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
-         {
-           *walk_subtrees = 0;
-           if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
-             cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
-                           cp_genericize_r, data, NULL);
-         }
-       break;
-      case OMP_CLAUSE_PRIVATE:
-       /* Don't dereference an invisiref in OpenMP clauses.  */
-       if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+    case ADDR_EXPR:
+      if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+       {
+         /* If in an OpenMP context, note var uses.  */
+         if (__builtin_expect (wtd->omp_ctx != NULL, 0)
+             && omp_var_to_track (TREE_OPERAND (stmt, 0)))
+           omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
+         *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
          *walk_subtrees = 0;
-       else if (wtd->omp_ctx != NULL)
-         {
-           /* Private clause doesn't cause any references to the
-              var in outer contexts, avoid calling
-              omp_cxx_notice_variable for it.  */
-           struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
-           wtd->omp_ctx = NULL;
-           cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
-                         data, NULL);
-           wtd->omp_ctx = old;
+       }
+      break;
+
+    case RETURN_EXPR:
+      if (TREE_OPERAND (stmt, 0) && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
+       /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
+       *walk_subtrees = 0;
+      break;
+
+    case OMP_CLAUSE:
+      switch (OMP_CLAUSE_CODE (stmt))
+       {
+       case OMP_CLAUSE_LASTPRIVATE:
+         /* Don't dereference an invisiref in OpenMP clauses.  */
+         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+           {
+             *walk_subtrees = 0;
+             if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
+               cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
+                             cp_genericize_r, data, NULL);
+           }
+         break;
+       case OMP_CLAUSE_PRIVATE:
+         /* Don't dereference an invisiref in OpenMP clauses.  */
+         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
            *walk_subtrees = 0;
-         }
-       break;
-      case OMP_CLAUSE_SHARED:
-      case OMP_CLAUSE_FIRSTPRIVATE:
-      case OMP_CLAUSE_COPYIN:
-      case OMP_CLAUSE_COPYPRIVATE:
-       /* Don't dereference an invisiref in OpenMP clauses.  */
-       if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
-         *walk_subtrees = 0;
-       break;
-      case OMP_CLAUSE_REDUCTION:
-       /* Don't dereference an invisiref in reduction clause's
-          OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
-          still needs to be genericized.  */
-       if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
-         {
+         else if (wtd->omp_ctx != NULL)
+           {
+             /* Private clause doesn't cause any references to the
+                var in outer contexts, avoid calling
+                omp_cxx_notice_variable for it.  */
+             struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
+             wtd->omp_ctx = NULL;
+             cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
+                           data, NULL);
+             wtd->omp_ctx = old;
+             *walk_subtrees = 0;
+           }
+         break;
+       case OMP_CLAUSE_SHARED:
+       case OMP_CLAUSE_FIRSTPRIVATE:
+       case OMP_CLAUSE_COPYIN:
+       case OMP_CLAUSE_COPYPRIVATE:
+         /* Don't dereference an invisiref in OpenMP clauses.  */
+         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
            *walk_subtrees = 0;
-           if (OMP_CLAUSE_REDUCTION_INIT (stmt))
-             cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
-                           cp_genericize_r, data, NULL);
-           if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
-             cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
-                           cp_genericize_r, data, NULL);
-         }
-       break;
-      default:
-       break;
-      }
-  else if (IS_TYPE_OR_DECL_P (stmt))
-    *walk_subtrees = 0;
-
-  /* Due to the way voidify_wrapper_expr is written, we don't get a chance
-     to lower this construct before scanning it, so we need to lower these
-     before doing anything else.  */
-  else if (TREE_CODE (stmt) == CLEANUP_STMT)
-    *stmt_p = build2_loc (EXPR_LOCATION (stmt),
-                         CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
-                                                : TRY_FINALLY_EXPR,
-                         void_type_node,
-                         CLEANUP_BODY (stmt),
-                         CLEANUP_EXPR (stmt));
-
-  else if (TREE_CODE (stmt) == IF_STMT)
-    {
+         break;
+       case OMP_CLAUSE_REDUCTION:
+         /* Don't dereference an invisiref in reduction clause's
+            OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
+            still needs to be genericized.  */
+         if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
+           {
+             *walk_subtrees = 0;
+             if (OMP_CLAUSE_REDUCTION_INIT (stmt))
+               cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
+                             cp_genericize_r, data, NULL);
+             if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
+               cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
+                             cp_genericize_r, data, NULL);
+           }
+         break;
+       default:
+         break;
+       }
+      break;
+
+    /* Due to the way voidify_wrapper_expr is written, we don't get a chance
+       to lower this construct before scanning it, so we need to lower these
+       before doing anything else.  */
+    case CLEANUP_STMT:
+      *stmt_p = build2_loc (EXPR_LOCATION (stmt),
+                           CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
+                                                  : TRY_FINALLY_EXPR,
+                           void_type_node,
+                           CLEANUP_BODY (stmt),
+                           CLEANUP_EXPR (stmt));
+      break;
+
+    case IF_STMT:
       genericize_if_stmt (stmt_p);
       /* *stmt_p has changed, tail recurse to handle it again.  */
       return cp_genericize_r (stmt_p, walk_subtrees, data);
-    }
 
-  /* COND_EXPR might have incompatible types in branches if one or both
-     arms are bitfields.  Fix it up now.  */
-  else if (TREE_CODE (stmt) == COND_EXPR)
-    {
-      tree type_left
-       = (TREE_OPERAND (stmt, 1)
-          ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
-          : NULL_TREE);
-      tree type_right
-       = (TREE_OPERAND (stmt, 2)
-          ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
-          : NULL_TREE);
-      if (type_left
-         && !useless_type_conversion_p (TREE_TYPE (stmt),
-                                        TREE_TYPE (TREE_OPERAND (stmt, 1))))
-       {
-         TREE_OPERAND (stmt, 1)
-           = fold_convert (type_left, TREE_OPERAND (stmt, 1));
-         gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
-                                                type_left));
-       }
-      if (type_right
-         && !useless_type_conversion_p (TREE_TYPE (stmt),
-                                        TREE_TYPE (TREE_OPERAND (stmt, 2))))
-       {
-         TREE_OPERAND (stmt, 2)
-           = fold_convert (type_right, TREE_OPERAND (stmt, 2));
-         gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
-                                                type_right));
-       }
-    }
+    /* COND_EXPR might have incompatible types in branches if one or both
+       arms are bitfields.  Fix it up now.  */
+    case COND_EXPR:
+      {
+       tree type_left
+         = (TREE_OPERAND (stmt, 1)
+            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
+            : NULL_TREE);
+       tree type_right
+         = (TREE_OPERAND (stmt, 2)
+            ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
+            : NULL_TREE);
+       if (type_left
+           && !useless_type_conversion_p (TREE_TYPE (stmt),
+                                          TREE_TYPE (TREE_OPERAND (stmt, 1))))
+         {
+           TREE_OPERAND (stmt, 1)
+             = fold_convert (type_left, TREE_OPERAND (stmt, 1));
+           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
+                                                  type_left));
+         }
+       if (type_right
+           && !useless_type_conversion_p (TREE_TYPE (stmt),
+                                          TREE_TYPE (TREE_OPERAND (stmt, 2))))
+         {
+           TREE_OPERAND (stmt, 2)
+             = fold_convert (type_right, TREE_OPERAND (stmt, 2));
+           gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
+                                                  type_right));
+         }
+      }
+      break;
 
-  else if (TREE_CODE (stmt) == BIND_EXPR)
-    {
+    case BIND_EXPR:
       if (__builtin_expect (wtd->omp_ctx != NULL, 0))
        {
          tree decl;
@@ -1281,113 +1284,118 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       cp_walk_tree (&BIND_EXPR_BODY (stmt),
                    cp_genericize_r, data, NULL);
       wtd->bind_expr_stack.pop ();
-    }
+      break;
 
-  else if (TREE_CODE (stmt) == USING_STMT)
-    {
-      tree block = NULL_TREE;
+    case USING_STMT:
+      {
+       tree block = NULL_TREE;
+
+       /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
+          BLOCK, and append an IMPORTED_DECL to its
+          BLOCK_VARS chained list.  */
+       if (wtd->bind_expr_stack.exists ())
+         {
+           int i;
+           for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
+             if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
+               break;
+         }
+       if (block)
+         {
+           tree using_directive;
+           gcc_assert (TREE_OPERAND (stmt, 0));
 
-      /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
-         BLOCK, and append an IMPORTED_DECL to its
-        BLOCK_VARS chained list.  */
-      if (wtd->bind_expr_stack.exists ())
+           using_directive = make_node (IMPORTED_DECL);
+           TREE_TYPE (using_directive) = void_type_node;
+
+           IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
+             = TREE_OPERAND (stmt, 0);
+           DECL_CHAIN (using_directive) = BLOCK_VARS (block);
+           BLOCK_VARS (block) = using_directive;
+         }
+       /* The USING_STMT won't appear in GENERIC.  */
+       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+       *walk_subtrees = 0;
+      }
+      break;
+
+    case DECL_EXPR:
+      if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
        {
-         int i;
-         for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
-           if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
-             break;
+         /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
+         *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
+         *walk_subtrees = 0;
        }
-      if (block)
+      else
        {
-         tree using_directive;
-         gcc_assert (TREE_OPERAND (stmt, 0));
-
-         using_directive = make_node (IMPORTED_DECL);
-         TREE_TYPE (using_directive) = void_type_node;
-
-         IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
-           = TREE_OPERAND (stmt, 0);
-         DECL_CHAIN (using_directive) = BLOCK_VARS (block);
-         BLOCK_VARS (block) = using_directive;
+         tree d = DECL_EXPR_DECL (stmt);
+         if (VAR_P (d))
+           gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
        }
-      /* The USING_STMT won't appear in GENERIC.  */
-      *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
-      *walk_subtrees = 0;
-    }
-
-  else if (TREE_CODE (stmt) == DECL_EXPR
-          && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
-    {
-      /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
-      *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
-      *walk_subtrees = 0;
-    }
-  else if (TREE_CODE (stmt) == DECL_EXPR)
-    {
-      tree d = DECL_EXPR_DECL (stmt);
-      if (VAR_P (d))
-       gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
-    }
-  else if (TREE_CODE (stmt) == OMP_PARALLEL
-          || TREE_CODE (stmt) == OMP_TASK
-          || TREE_CODE (stmt) == OMP_TASKLOOP)
-    {
-      struct cp_genericize_omp_taskreg omp_ctx;
-      tree c, decl;
-      splay_tree_node n;
+      break;
 
-      *walk_subtrees = 0;
-      cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
-      omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
-      omp_ctx.default_shared = omp_ctx.is_parallel;
-      omp_ctx.outer = wtd->omp_ctx;
-      omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
-      wtd->omp_ctx = &omp_ctx;
-      for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
-       switch (OMP_CLAUSE_CODE (c))
-         {
-         case OMP_CLAUSE_SHARED:
-         case OMP_CLAUSE_PRIVATE:
-         case OMP_CLAUSE_FIRSTPRIVATE:
-         case OMP_CLAUSE_LASTPRIVATE:
-           decl = OMP_CLAUSE_DECL (c);
-           if (decl == error_mark_node || !omp_var_to_track (decl))
+    case OMP_PARALLEL:
+    case OMP_TASK:
+    case OMP_TASKLOOP:
+      {
+       struct cp_genericize_omp_taskreg omp_ctx;
+       tree c, decl;
+       splay_tree_node n;
+
+       *walk_subtrees = 0;
+       cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
+       omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
+       omp_ctx.default_shared = omp_ctx.is_parallel;
+       omp_ctx.outer = wtd->omp_ctx;
+       omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
+       wtd->omp_ctx = &omp_ctx;
+       for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
+         switch (OMP_CLAUSE_CODE (c))
+           {
+           case OMP_CLAUSE_SHARED:
+           case OMP_CLAUSE_PRIVATE:
+           case OMP_CLAUSE_FIRSTPRIVATE:
+           case OMP_CLAUSE_LASTPRIVATE:
+             decl = OMP_CLAUSE_DECL (c);
+             if (decl == error_mark_node || !omp_var_to_track (decl))
+               break;
+             n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
+             if (n != NULL)
+               break;
+             splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
+                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
+                                ? OMP_CLAUSE_DEFAULT_SHARED
+                                : OMP_CLAUSE_DEFAULT_PRIVATE);
+             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
+               omp_cxx_notice_variable (omp_ctx.outer, decl);
              break;
-           n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
-           if (n != NULL)
+           case OMP_CLAUSE_DEFAULT:
+             if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
+               omp_ctx.default_shared = true;
+           default:
              break;
-           splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
-                              OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
-                              ? OMP_CLAUSE_DEFAULT_SHARED
-                              : OMP_CLAUSE_DEFAULT_PRIVATE);
-           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
-               && omp_ctx.outer)
-             omp_cxx_notice_variable (omp_ctx.outer, decl);
-           break;
-         case OMP_CLAUSE_DEFAULT:
-           if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
-             omp_ctx.default_shared = true;
-         default:
-           break;
-         }
-      if (TREE_CODE (stmt) == OMP_TASKLOOP)
-       genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
-      else
-       cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
-      wtd->omp_ctx = omp_ctx.outer;
-      splay_tree_delete (omp_ctx.variables);
-    }
-  else if (TREE_CODE (stmt) == TRY_BLOCK)
-    {
-      *walk_subtrees = 0;
-      tree try_block = wtd->try_block;
-      wtd->try_block = stmt;
-      cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
-      wtd->try_block = try_block;
-      cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
-    }
-  else if (TREE_CODE (stmt) == MUST_NOT_THROW_EXPR)
-    {
+           }
+       if (TREE_CODE (stmt) == OMP_TASKLOOP)
+         genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
+       else
+         cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
+       wtd->omp_ctx = omp_ctx.outer;
+       splay_tree_delete (omp_ctx.variables);
+      }
+      break;
+
+    case TRY_BLOCK:
+      {
+        *walk_subtrees = 0;
+        tree try_block = wtd->try_block;
+        wtd->try_block = stmt;
+        cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
+        wtd->try_block = try_block;
+        cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
+      }
+      break;
+
+    case MUST_NOT_THROW_EXPR:
       /* MUST_NOT_THROW_COND might be something else with TM.  */
       if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
        {
@@ -1397,78 +1405,99 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
          cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
          wtd->try_block = try_block;
        }
-    }
-  else if (TREE_CODE (stmt) == THROW_EXPR)
-    {
-      location_t loc = location_of (stmt);
-      if (TREE_NO_WARNING (stmt))
-       /* Never mind.  */;
-      else if (wtd->try_block)
-       {
-         if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR
-             && warning_at (loc, OPT_Wterminate,
-                            "throw will always call terminate()")
-             && cxx_dialect >= cxx11
-             && DECL_DESTRUCTOR_P (current_function_decl))
-           inform (loc, "in C++11 destructors default to noexcept");
-       }
-      else
-       {
-         if (warn_cxx11_compat && cxx_dialect < cxx11
-             && DECL_DESTRUCTOR_P (current_function_decl)
-             && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
-                 == NULL_TREE)
-             && (get_defaulted_eh_spec (current_function_decl)
-                 == empty_except_spec))
-           warning_at (loc, OPT_Wc__11_compat,
-                       "in C++11 this throw will terminate because "
-                       "destructors default to noexcept");
-       }
-    }
-  else if (TREE_CODE (stmt) == CONVERT_EXPR)
-    gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
-  else if (TREE_CODE (stmt) == FOR_STMT)
-    genericize_for_stmt (stmt_p, walk_subtrees, data);
-  else if (TREE_CODE (stmt) == WHILE_STMT)
-    genericize_while_stmt (stmt_p, walk_subtrees, data);
-  else if (TREE_CODE (stmt) == DO_STMT)
-    genericize_do_stmt (stmt_p, walk_subtrees, data);
-  else if (TREE_CODE (stmt) == SWITCH_STMT)
-    genericize_switch_stmt (stmt_p, walk_subtrees, data);
-  else if (TREE_CODE (stmt) == CONTINUE_STMT)
-    genericize_continue_stmt (stmt_p);
-  else if (TREE_CODE (stmt) == BREAK_STMT)
-    genericize_break_stmt (stmt_p);
-  else if (TREE_CODE (stmt) == OMP_FOR
-          || TREE_CODE (stmt) == OMP_SIMD
-          || TREE_CODE (stmt) == OMP_DISTRIBUTE)
-    genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
-  else if (TREE_CODE (stmt) == PTRMEM_CST)
-    {
+      break;
+
+    case THROW_EXPR:
+      {
+       location_t loc = location_of (stmt);
+       if (TREE_NO_WARNING (stmt))
+         /* Never mind.  */;
+       else if (wtd->try_block)
+         {
+           if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR
+               && warning_at (loc, OPT_Wterminate,
+                              "throw will always call terminate()")
+               && cxx_dialect >= cxx11
+               && DECL_DESTRUCTOR_P (current_function_decl))
+             inform (loc, "in C++11 destructors default to noexcept");
+         }
+       else
+         {
+           if (warn_cxx11_compat && cxx_dialect < cxx11
+               && DECL_DESTRUCTOR_P (current_function_decl)
+               && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
+                   == NULL_TREE)
+               && (get_defaulted_eh_spec (current_function_decl)
+                   == empty_except_spec))
+             warning_at (loc, OPT_Wc__11_compat,
+                         "in C++11 this throw will terminate because "
+                         "destructors default to noexcept");
+         }
+      }
+      break;
+
+    case CONVERT_EXPR:
+      gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
+      break;
+
+    case FOR_STMT:
+      genericize_for_stmt (stmt_p, walk_subtrees, data);
+      break;
+
+    case WHILE_STMT:
+      genericize_while_stmt (stmt_p, walk_subtrees, data);
+      break;
+
+    case DO_STMT:
+      genericize_do_stmt (stmt_p, walk_subtrees, data);
+      break;
+
+    case SWITCH_STMT:
+      genericize_switch_stmt (stmt_p, walk_subtrees, data);
+      break;
+
+    case CONTINUE_STMT:
+      genericize_continue_stmt (stmt_p);
+      break;
+
+    case BREAK_STMT:
+      genericize_break_stmt (stmt_p);
+      break;
+
+    case OMP_FOR:
+    case OMP_SIMD:
+    case OMP_DISTRIBUTE:
+      genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
+      break;
+
+    case PTRMEM_CST:
       /* By the time we get here we're handing off to the back end, so we don't
         need or want to preserve PTRMEM_CST anymore.  */
       *stmt_p = cplus_expand_constant (stmt);
       *walk_subtrees = 0;
-    }
-  else if (TREE_CODE (stmt) == MEM_REF)
-    {
+      break;
+
+    case MEM_REF:
       /* For MEM_REF, make sure not to sanitize the second operand even
-         if it has reference type.  It is just an offset with a type
+        if it has reference type.  It is just an offset with a type
         holding other information.  There is no other processing we
         need to do for INTEGER_CSTs, so just ignore the second argument
         unconditionally.  */
       cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
       *walk_subtrees = 0;
-    }
-  else if (sanitize_flags_p ((SANITIZE_NULL
-                             | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
-          && !wtd->no_sanitize_p)
-    {
-      if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
-         && TREE_CODE (stmt) == NOP_EXPR
+      break;
+
+    case NOP_EXPR:
+      if (!wtd->no_sanitize_p
+         && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
          && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE)
        ubsan_maybe_instrument_reference (stmt_p);
-      else if (TREE_CODE (stmt) == CALL_EXPR)
+      break;
+
+    case CALL_EXPR:
+      if (!wtd->no_sanitize_p
+         && sanitize_flags_p ((SANITIZE_NULL
+                               | SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
        {
          tree fn = CALL_EXPR_FN (stmt);
          if (fn != NULL_TREE
@@ -1486,6 +1515,12 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
                cp_ubsan_maybe_instrument_member_call (stmt);
            }
        }
+      break;
+
+    default:
+      if (IS_TYPE_OR_DECL_P (stmt))
+       *walk_subtrees = 0;
+      break;
     }
 
   p_set->add (*stmt_p);