aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-05-19 16:04:22 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-05-19 16:04:22 +0000
commiteaf6fb906eb9e8807f068dd917a738523382bfe2 (patch)
tree87a70819ab712edee728af13b2ec95fe70702bdf /gcc/cp
parentaffaef6e07c544cef985d95e213b6942fe1988da (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/cp/pt.c6
-rw-r--r--gcc/cp/semantics.c19
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. */