diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-05-19 16:04:22 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-05-19 16:04:22 +0000 |
commit | eaf6fb906eb9e8807f068dd917a738523382bfe2 (patch) | |
tree | 87a70819ab712edee728af13b2ec95fe70702bdf /gcc/cp | |
parent | affaef6e07c544cef985d95e213b6942fe1988da (diff) | |
download | gcc-eaf6fb906eb9e8807f068dd917a738523382bfe2.zip gcc-eaf6fb906eb9e8807f068dd917a738523382bfe2.tar.gz gcc-eaf6fb906eb9e8807f068dd917a738523382bfe2.tar.bz2 |
re PR c++/26433 (Syntax error using __FUNCTION__ in catch handler)
PR c++/26433
* cp-tree.h (begin_function_try_block): Change prototype.
(finish_function_handler_sequence): Likewise.
* parser.c (cp_parser_function_try_block): Adjust calls.
* pt.c (tsubst_expr): Adjust calls.
* semantics.c (begin_function_try_block): Create an artificial
outer scope.
(finish_function_handler_sequence): Close it.
PR c++/26433
* g++.dg/template/fntry1.C: New test.
From-SVN: r113911
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 19 |
5 files changed, 34 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3c13cc0..4308862 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2006-05-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/26433 + * cp-tree.h (begin_function_try_block): Change prototype. + (finish_function_handler_sequence): Likewise. + * parser.c (cp_parser_function_try_block): Adjust calls. + * pt.c (tsubst_expr): Adjust calls. + * semantics.c (begin_function_try_block): Create an artificial + outer scope. + (finish_function_handler_sequence): Close it. + 2006-05-18 Mark Mitchell <mark@codesourcery.com> PR c++/27471 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index cac801d..ed5c330 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4190,9 +4190,9 @@ extern void finish_try_block (tree); extern tree begin_eh_spec_block (void); extern void finish_eh_spec_block (tree, tree); extern void finish_handler_sequence (tree); -extern tree begin_function_try_block (void); +extern tree begin_function_try_block (tree *); extern void finish_function_try_block (tree); -extern void finish_function_handler_sequence (tree); +extern void finish_function_handler_sequence (tree, tree); extern void finish_cleanup_try_block (tree); extern tree begin_handler (void); extern void finish_handler_parms (tree, tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e80b8ee..74934fb 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14225,6 +14225,7 @@ cp_parser_try_block (cp_parser* parser) static bool cp_parser_function_try_block (cp_parser* parser) { + tree compound_stmt; tree try_block; bool ctor_initializer_p; @@ -14232,7 +14233,7 @@ cp_parser_function_try_block (cp_parser* parser) if (!cp_parser_require_keyword (parser, RID_TRY, "`try'")) return false; /* Let the rest of the front-end know where we are. */ - try_block = begin_function_try_block (); + try_block = begin_function_try_block (&compound_stmt); /* Parse the function-body. */ ctor_initializer_p = cp_parser_ctor_initializer_opt_and_function_body (parser); @@ -14241,7 +14242,7 @@ cp_parser_function_try_block (cp_parser* parser) /* Parse the handlers. */ cp_parser_handler_seq (parser); /* We're done with the handlers. */ - finish_function_handler_sequence (try_block); + finish_function_handler_sequence (try_block, compound_stmt); return ctor_initializer_p; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ea3ff41..8db24ca 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8405,8 +8405,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) } else { + tree compound_stmt = NULL_TREE; + if (FN_TRY_BLOCK_P (t)) - stmt = begin_function_try_block (); + stmt = begin_function_try_block (&compound_stmt); else stmt = begin_try_block (); @@ -8419,7 +8421,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl); if (FN_TRY_BLOCK_P (t)) - finish_function_handler_sequence (stmt); + finish_function_handler_sequence (stmt, compound_stmt); else finish_handler_sequence (stmt); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f7a3b40..6af4564 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -975,12 +975,18 @@ begin_try_block (void) return r; } -/* Likewise, for a function-try-block. */ +/* Likewise, for a function-try-block. The block returned in + *COMPOUND_STMT is an artificial outer scope, containing the + function-try-block. */ tree -begin_function_try_block (void) +begin_function_try_block (tree *compound_stmt) { - tree r = begin_try_block (); + tree r; + /* This outer scope does not exist in the C++ standard, but we need + a place to put __FUNCTION__ and similar variables. */ + *compound_stmt = begin_compound_stmt (0); + r = begin_try_block (); FN_TRY_BLOCK_P (r) = 1; return r; } @@ -1034,13 +1040,16 @@ finish_handler_sequence (tree try_block) check_handlers (TRY_HANDLERS (try_block)); } -/* Likewise, for a function-try-block. */ +/* Finish the handler-seq for a function-try-block, given by + TRY_BLOCK. COMPOUND_STMT is the outer block created by + begin_function_try_block. */ void -finish_function_handler_sequence (tree try_block) +finish_function_handler_sequence (tree try_block, tree compound_stmt) { in_function_try_handler = 0; finish_handler_sequence (try_block); + finish_compound_stmt (compound_stmt); } /* Begin a handler. Returns a HANDLER if appropriate. */ |