Commit 2c443701 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/67409 (tree-cfg.c dereferences a NULL pointer)

	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 <manu@gcc.gnu.org>

From-SVN: r230613
parent 1e1ce42e
2015-11-19 Jakub Jelinek <jakub@redhat.com>
Manuel López-Ibáñez <manu@gcc.gnu.org>
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 <matz@suse.de> 2015-11-19 Michael Matz <matz@suse.de>
* fwprop.c (update_uses): Use flag_checking instead of * fwprop.c (update_uses): Use flag_checking instead of
...@@ -2967,14 +2967,16 @@ decl_jump_unsafe (tree decl) ...@@ -2967,14 +2967,16 @@ decl_jump_unsafe (tree decl)
return 0; 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 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 bool complained
? permerror (input_location, "jump to label %qD", decl) = (decl ? emit_diagnostic (diag_kind, loc, 0, "jump to label %qD", decl)
: permerror (input_location, "jump to case label")); : emit_diagnostic (diag_kind, loc, 0, "jump to case label"));
if (complained && locus) if (complained && locus)
inform (*locus, " from here"); inform (*locus, " from here");
return complained; return complained;
...@@ -2991,15 +2993,17 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, ...@@ -2991,15 +2993,17 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
bool exited_omp, const location_t *locus) bool exited_omp, const location_t *locus)
{ {
cp_binding_level *b; 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; bool saw_eh = false, saw_omp = false, saw_tm = false;
if (exited_omp) if (exited_omp)
{ {
complained = identify_goto (decl, locus); complained = identify_goto (decl, input_location, locus, DK_ERROR);
if (complained) if (complained)
inform (input_location, " exits OpenMP structured block"); 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) 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, ...@@ -3016,8 +3020,9 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
if (!identified) if (!identified)
{ {
complained = identify_goto (decl, locus); complained = identify_goto (decl, input_location, locus,
identified = true; DK_PERMERROR);
identified = 1;
} }
if (complained) if (complained)
{ {
...@@ -3035,10 +3040,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, ...@@ -3035,10 +3040,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
break; break;
if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh) if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh)
{ {
if (!identified) if (identified < 2)
{ {
complained = identify_goto (decl, locus); complained = identify_goto (decl, input_location, locus,
identified = true; DK_ERROR);
identified = 2;
} }
if (complained) if (complained)
{ {
...@@ -3051,10 +3057,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, ...@@ -3051,10 +3057,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
} }
if (b->kind == sk_omp && !saw_omp) if (b->kind == sk_omp && !saw_omp)
{ {
if (!identified) if (identified < 2)
{ {
complained = identify_goto (decl, locus); complained = identify_goto (decl, input_location, locus,
identified = true; DK_ERROR);
identified = 2;
} }
if (complained) if (complained)
inform (input_location, " enters OpenMP structured block"); inform (input_location, " enters OpenMP structured block");
...@@ -3062,10 +3069,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, ...@@ -3062,10 +3069,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
} }
if (b->kind == sk_transaction && !saw_tm) if (b->kind == sk_transaction && !saw_tm)
{ {
if (!identified) if (identified < 2)
{ {
complained = identify_goto (decl, locus); complained = identify_goto (decl, input_location, locus,
identified = true; DK_ERROR);
identified = 2;
} }
if (complained) if (complained)
inform (input_location, inform (input_location,
...@@ -3098,7 +3106,8 @@ void ...@@ -3098,7 +3106,8 @@ void
check_goto (tree decl) check_goto (tree decl)
{ {
struct named_label_entry *ent, dummy; 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; tree bad;
unsigned ix; unsigned ix;
...@@ -3141,11 +3150,13 @@ check_goto (tree decl) ...@@ -3141,11 +3150,13 @@ check_goto (tree decl)
if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope
|| ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls)) || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
{ {
complained = permerror (DECL_SOURCE_LOCATION (decl), diagnostic_t diag_kind = DK_PERMERROR;
"jump to label %qD", decl); if (ent->in_try_scope || ent->in_catch_scope
if (complained) || ent->in_transaction_scope || ent->in_omp_scope)
inform (input_location, " from here"); diag_kind = DK_ERROR;
identified = true; 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) FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
...@@ -3155,6 +3166,12 @@ check_goto (tree decl) ...@@ -3155,6 +3166,12 @@ check_goto (tree decl)
if (u > 1 && DECL_ARTIFICIAL (bad)) if (u > 1 && DECL_ARTIFICIAL (bad))
{ {
/* Can't skip init of __exception_info. */ /* 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) if (complained)
inform (DECL_SOURCE_LOCATION (bad), " enters catch block"); inform (DECL_SOURCE_LOCATION (bad), " enters catch block");
saw_catch = true; saw_catch = true;
...@@ -3195,13 +3212,12 @@ check_goto (tree decl) ...@@ -3195,13 +3212,12 @@ check_goto (tree decl)
break; break;
if (b->kind == sk_omp) if (b->kind == sk_omp)
{ {
if (!identified) if (identified < 2)
{ {
complained = permerror (DECL_SOURCE_LOCATION (decl), complained = identify_goto (decl,
"jump to label %qD", decl); DECL_SOURCE_LOCATION (decl),
if (complained) &input_location, DK_ERROR);
inform (input_location, " from here"); identified = 2;
identified = true;
} }
if (complained) if (complained)
inform (input_location, " exits OpenMP structured block"); inform (input_location, " exits OpenMP structured block");
......
2015-11-19 Jakub Jelinek <jakub@redhat.com>
PR c++/67409
* g++.dg/eh/goto3.C: New test.
2015-11-19 Marek Polacek <polacek@redhat.com> 2015-11-19 Marek Polacek <polacek@redhat.com>
PR tree-optimization/68431 PR tree-optimization/68431
......
// 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" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment