From cc9e1a64c659adf7271e0d380faf31dd1fcc0e00 Mon Sep 17 00:00:00 2001 From: jakub Date: Wed, 14 Jun 2017 11:24:48 +0000 Subject: [PATCH] * cp-gimplify.c (cp_genericize_r): Turn most of the function into a switch (TREE_CODE (stmt)) statement from long else if sequence. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@249191 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 + gcc/cp/cp-gimplify.c | 585 +++++++++++++++++++++++++++------------------------ 2 files changed, 316 insertions(+), 275 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ca0f9b20014..b933392d583 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-06-14 Jakub Jelinek + + * 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 PR c++/80973 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index a0abd51440d..f010f6c63be 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -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); -- 2.11.4.GIT