This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Issue hard error even with -fpermissive for certain goto violations (PR c++/67409, take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Manuel López-Ibáñez <lopezibanez at gmail dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 Nov 2015 13:39:13 +0100
- Subject: [C++ PATCH] Issue hard error even with -fpermissive for certain goto violations (PR c++/67409, take 2)
- Authentication-results: sourceware.org; auth=none
- References: <20151118225520 dot GN5675 at tucnak dot redhat dot com> <564D3987 dot 4050908 at gmail dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Nov 19, 2015 at 02:52:55AM +0000, Manuel López-Ibáñez wrote:
> static bool
> error_jumpto (diagnostic_t kind, location_t loc, tree decl)
> {
> bool complained = (decl
> ? emit_diagnostic (kind, input_location, 0,
> "jump to label %qD", decl)
> : emit_diagnostic (kind, input_location, 0,
> "jump to case label"));
> if (complained && loc)
> inform (loc, " from here");
> return complained;
> }
Thanks for the suggestion. That said, I see no reason to rename the
function, or reverse the order of arguments (seems typeck2.c routines
that call emit_diagnostic also have diagnostic_t diag_kind last).
And I really need two locations, not just one, so that it can be used
in both check_previous_goto_1 and check_goto.
So, here is an updated patch, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk/5.3?
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.
* g++.dg/eh/goto3.C: New test.
--- gcc/cp/decl.c.jj 2015-11-19 09:16:02.675919026 +0100
+++ gcc/cp/decl.c 2015-11-19 10:47:09.317990016 +0100
@@ -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_bin
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_bin
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_bin
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_bin
}
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_bin
}
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");
--- gcc/testsuite/g++.dg/eh/goto3.C.jj 2015-11-19 10:16:57.304807040 +0100
+++ gcc/testsuite/g++.dg/eh/goto3.C 2015-11-19 10:16:57.304807040 +0100
@@ -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" }
+ }
Jakub