OSDN Git Service

PR c++/26433
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 May 2006 16:04:22 +0000 (16:04 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 May 2006 16:04:22 +0000 (16:04 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113911 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/fntry1.C [new file with mode: 0644]

index 3c13cc0..4308862 100644 (file)
@@ -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
index cac801d..ed5c330 100644 (file)
@@ -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);
index e80b8ee..74934fb 100644 (file)
@@ -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;
 }
index ea3ff41..8db24ca 100644 (file)
@@ -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);
        }
index f7a3b40..6af4564 100644 (file)
@@ -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.  */
index 540995b..78025fc 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-19  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/26433
+       * g++.dg/template/fntry1.C: New test.
+
 2006-05-18  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/27471
diff --git a/gcc/testsuite/g++.dg/template/fntry1.C b/gcc/testsuite/g++.dg/template/fntry1.C
new file mode 100644 (file)
index 0000000..80b2aff
--- /dev/null
@@ -0,0 +1,42 @@
+// PR c++/26433
+
+int get_int()
+{
+  throw 1;
+
+  return 0;
+}
+
+template <class _T> class Test
+{
+public:
+  Test()
+        try
+       : i(get_int())
+  {
+    i++;
+  }
+  catch(...)
+  {
+    // Syntax error caused by undefined __FUNCTION__.
+    const char* ptr = __FUNCTION__;
+  }
+
+private:
+  int i;
+  _T t;
+};
+
+int main()
+{
+    try
+      {
+        Test<int> test;
+      }
+    catch(...)
+      {
+        return 1;
+      }
+
+    return 0;
+}