Skip to content

Commit 2488771

Browse files
committed
c++: computed goto from catch block [PR81438]
As with 37722, we don't clean up the exception object if a computed goto leaves a catch block, but we can warn about that. PR c++/81438 gcc/cp/ChangeLog: * decl.cc (poplevel_named_label_1): Handle leaving catch. (check_previous_goto_1): Likewise. (check_goto_1): Likewise. gcc/testsuite/ChangeLog: * g++.dg/ext/label15.C: Require indirect_jumps. * g++.dg/ext/label16.C: New test.
1 parent 5cb79aa commit 2488771

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

gcc/cp/decl.cc

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -571,10 +571,14 @@ poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl)
571571
if (use->binding_level == bl)
572572
{
573573
if (auto &cg = use->computed_goto)
574-
for (tree d = use->names_in_scope; d; d = DECL_CHAIN (d))
575-
if (TREE_CODE (d) == VAR_DECL && !TREE_STATIC (d)
576-
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (d)))
577-
vec_safe_push (cg, d);
574+
{
575+
if (bl->kind == sk_catch)
576+
vec_safe_push (cg, get_identifier ("catch"));
577+
for (tree d = use->names_in_scope; d; d = DECL_CHAIN (d))
578+
if (TREE_CODE (d) == VAR_DECL && !TREE_STATIC (d)
579+
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (d)))
580+
vec_safe_push (cg, d);
581+
}
578582

579583
use->binding_level = obl;
580584
use->names_in_scope = obl->names;
@@ -3820,7 +3824,12 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
38203824
identified = 2;
38213825
if (complained)
38223826
for (tree d : computed)
3823-
inform (DECL_SOURCE_LOCATION (d), " does not destroy %qD", d);
3827+
{
3828+
if (DECL_P (d))
3829+
inform (DECL_SOURCE_LOCATION (d), " does not destroy %qD", d);
3830+
else if (d == get_identifier ("catch"))
3831+
inform (*locus, " does not clean up handled exception");
3832+
}
38243833
}
38253834

38263835
return !identified;
@@ -3963,15 +3972,32 @@ check_goto_1 (named_label_entry *ent, bool computed)
39633972
auto names = ent->names_in_scope;
39643973
for (auto b = current_binding_level; ; b = b->level_chain)
39653974
{
3975+
if (b->kind == sk_catch)
3976+
{
3977+
if (!identified)
3978+
{
3979+
complained
3980+
= identify_goto (decl, DECL_SOURCE_LOCATION (decl),
3981+
&input_location, DK_ERROR, computed);
3982+
identified = 2;
3983+
}
3984+
if (complained)
3985+
inform (input_location,
3986+
" does not clean up handled exception");
3987+
}
39663988
tree end = b == level ? names : NULL_TREE;
39673989
for (tree d = b->names; d != end; d = DECL_CHAIN (d))
39683990
{
39693991
if (TREE_CODE (d) == VAR_DECL && !TREE_STATIC (d)
39703992
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (d)))
39713993
{
3972-
complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
3973-
&input_location, DK_ERROR,
3974-
computed);
3994+
if (!identified)
3995+
{
3996+
complained
3997+
= identify_goto (decl, DECL_SOURCE_LOCATION (decl),
3998+
&input_location, DK_ERROR, computed);
3999+
identified = 2;
4000+
}
39754001
if (complained)
39764002
inform (DECL_SOURCE_LOCATION (d),
39774003
" does not destroy %qD", d);

gcc/testsuite/g++.dg/ext/label15.C

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// PR c++/37722
2+
// { dg-do compile { target indirect_jumps } }
23
// { dg-options "" }
34

45
extern "C" int printf (const char *, ...);

gcc/testsuite/g++.dg/ext/label16.C

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// PR c++/81438
2+
// { dg-do compile { target indirect_jumps } }
3+
// { dg-options "" }
4+
5+
bool b;
6+
int main()
7+
{
8+
try
9+
{
10+
try { throw 3; }
11+
catch(...) {
12+
h:; // { dg-warning "jump to label" }
13+
try { throw 7; }
14+
catch(...) {
15+
if (b)
16+
goto *&&h; // { dg-message "computed goto" }
17+
// { dg-message "handled exception" "" { target *-*-* } .-1 }
18+
else
19+
goto *&&g; // { dg-message "computed goto" }
20+
// { dg-message "handled exception" "" { target *-*-* } .-1 }
21+
}
22+
g:; // { dg-warning "jump to label" }
23+
throw;
24+
}
25+
}
26+
catch(int v)
27+
{
28+
__builtin_printf("%d\n", v);
29+
if(v != 3) // 7 because we don't clean up the catch on
30+
__builtin_abort(); // computed goto
31+
}
32+
33+
return 0;
34+
}

0 commit comments

Comments
 (0)