From 2c4437019f044d7d659e0cb36ff0afb461950977 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 19 Nov 2015 17:18:39 +0100 Subject: [PATCH] re PR c++/67409 (tree-cfg.c dereferences a NULL pointer) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit PR c++/67409 * decl.c (identify_goto): Add LOC and DIAG_KIND arguments, call emit_diagnostic instead of permerror. (check_previous_goto_1): Adjust identify_goto callers, treat all cases but crossing initialization and entering scope of decl with non-trivial dtor as unconditional hard errors. (check_goto): Use identify_goto. Treat all cases but crossing initialization and entering scope of decl with non-trivial dtor as unconditional hard errors. * g++.dg/eh/goto3.C: New test. Co-Authored-By: Manuel López-Ibáñez From-SVN: r230613 --- gcc/ChangeLog | 13 ++++++ gcc/cp/decl.c | 78 ++++++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/eh/goto3.C | 14 ++++++ 4 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/g++.dg/eh/goto3.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de3318c5540..1013d8fbd79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2015-11-19 Jakub Jelinek + Manuel López-Ibáñez + + PR c++/67409 + * decl.c (identify_goto): Add LOC and DIAG_KIND arguments, call + emit_diagnostic instead of permerror. + (check_previous_goto_1): Adjust identify_goto callers, treat all + cases but crossing initialization and entering scope of decl with + non-trivial dtor as unconditional hard errors. + (check_goto): Use identify_goto. Treat all cases but crossing + initialization and entering scope of decl with non-trivial dtor + as unconditional hard errors. + 2015-11-19 Michael Matz * fwprop.c (update_uses): Use flag_checking instead of diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 675342efcd9..e895c5a06ce 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2967,14 +2967,16 @@ decl_jump_unsafe (tree decl) return 0; } -/* A subroutine of check_previous_goto_1 to identify a branch to the user. */ +/* A subroutine of check_previous_goto_1 and check_goto to identify a branch + to the user. */ static bool -identify_goto (tree decl, const location_t *locus) +identify_goto (tree decl, location_t loc, const location_t *locus, + diagnostic_t diag_kind) { - bool complained = (decl - ? permerror (input_location, "jump to label %qD", decl) - : permerror (input_location, "jump to case label")); + bool complained + = (decl ? emit_diagnostic (diag_kind, loc, 0, "jump to label %qD", decl) + : emit_diagnostic (diag_kind, loc, 0, "jump to case label")); if (complained && locus) inform (*locus, " from here"); return complained; @@ -2991,15 +2993,17 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, bool exited_omp, const location_t *locus) { cp_binding_level *b; - bool identified = false, complained = false; + bool complained = false; + int identified = 0; bool saw_eh = false, saw_omp = false, saw_tm = false; if (exited_omp) { - complained = identify_goto (decl, locus); + complained = identify_goto (decl, input_location, locus, DK_ERROR); if (complained) inform (input_location, " exits OpenMP structured block"); - identified = saw_omp = true; + saw_omp = true; + identified = 2; } for (b = current_binding_level; b ; b = b->level_chain) @@ -3016,8 +3020,9 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, if (!identified) { - complained = identify_goto (decl, locus); - identified = true; + complained = identify_goto (decl, input_location, locus, + DK_PERMERROR); + identified = 1; } if (complained) { @@ -3035,10 +3040,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, break; if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh) { - if (!identified) + if (identified < 2) { - complained = identify_goto (decl, locus); - identified = true; + complained = identify_goto (decl, input_location, locus, + DK_ERROR); + identified = 2; } if (complained) { @@ -3051,10 +3057,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, } if (b->kind == sk_omp && !saw_omp) { - if (!identified) + if (identified < 2) { - complained = identify_goto (decl, locus); - identified = true; + complained = identify_goto (decl, input_location, locus, + DK_ERROR); + identified = 2; } if (complained) inform (input_location, " enters OpenMP structured block"); @@ -3062,10 +3069,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, } if (b->kind == sk_transaction && !saw_tm) { - if (!identified) + if (identified < 2) { - complained = identify_goto (decl, locus); - identified = true; + complained = identify_goto (decl, input_location, locus, + DK_ERROR); + identified = 2; } if (complained) inform (input_location, @@ -3098,7 +3106,8 @@ void check_goto (tree decl) { struct named_label_entry *ent, dummy; - bool saw_catch = false, identified = false, complained = false; + bool saw_catch = false, complained = false; + int identified = 0; tree bad; unsigned ix; @@ -3141,11 +3150,13 @@ check_goto (tree decl) if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls)) { - complained = permerror (DECL_SOURCE_LOCATION (decl), - "jump to label %qD", decl); - if (complained) - inform (input_location, " from here"); - identified = true; + diagnostic_t diag_kind = DK_PERMERROR; + if (ent->in_try_scope || ent->in_catch_scope + || ent->in_transaction_scope || ent->in_omp_scope) + diag_kind = DK_ERROR; + complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl), + &input_location, diag_kind); + identified = 1 + (diag_kind == DK_ERROR); } FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad) @@ -3155,6 +3166,12 @@ check_goto (tree decl) if (u > 1 && DECL_ARTIFICIAL (bad)) { /* Can't skip init of __exception_info. */ + if (identified == 1) + { + complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl), + &input_location, DK_ERROR); + identified = 2; + } if (complained) inform (DECL_SOURCE_LOCATION (bad), " enters catch block"); saw_catch = true; @@ -3195,13 +3212,12 @@ check_goto (tree decl) break; if (b->kind == sk_omp) { - if (!identified) + if (identified < 2) { - complained = permerror (DECL_SOURCE_LOCATION (decl), - "jump to label %qD", decl); - if (complained) - inform (input_location, " from here"); - identified = true; + complained = identify_goto (decl, + DECL_SOURCE_LOCATION (decl), + &input_location, DK_ERROR); + identified = 2; } if (complained) inform (input_location, " exits OpenMP structured block"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b6565914e4..2d4962d7489 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-19 Jakub Jelinek + + PR c++/67409 + * g++.dg/eh/goto3.C: New test. + 2015-11-19 Marek Polacek PR tree-optimization/68431 diff --git a/gcc/testsuite/g++.dg/eh/goto3.C b/gcc/testsuite/g++.dg/eh/goto3.C new file mode 100644 index 00000000000..d584ad76e81 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/goto3.C @@ -0,0 +1,14 @@ +// PR c++/67409 +// { dg-options "-fpermissive" } + +void f() +try + { + goto l2; // { dg-message "from here" } + l1: ; // { dg-error "jump to label 'l1'" } + } catch (...) + { + l2: ; // { dg-error "jump to label 'l2'" } + // { dg-message "enters catch block" "" { target *-*-*} 11 } + goto l1; // { dg-message "from here|enters try block" } + } -- 2.30.2