re PR c++/14724 (Destructor not called on backwards goto past initialization)
authorMark Mitchell <mark@codesourcery.com>
Tue, 30 Mar 2004 23:45:00 +0000 (23:45 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 30 Mar 2004 23:45:00 +0000 (23:45 +0000)
PR c++/14724
* decl.c (start_decl_1): Do not decide whether or not to create a
new cleanup level until after the type has been completed.

PR c++/14763
* pt.c (tsubst_default_argument): Clear current_function_decl.

PR c++/14724
* g++.dg/init/goto1.C: New test.

PR c++/14763
* g++.dg/template/defarg4.C: New test.

From-SVN: r80101

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/goto1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/defarg4.C [new file with mode: 0644]

index 6e3f71a1950156c52bdcf094aa75b563d73e6120..6fba6057b3f7d3c3abbef995a4fe701ed8938f90 100644 (file)
@@ -1,3 +1,12 @@
+2004-03-30  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/14724
+       * decl.c (start_decl_1): Do not decide whether or not to create a
+       new cleanup level until after the type has been completed.
+
+       PR c++/14763
+       * pt.c (tsubst_default_argument): Clear current_function_decl.
+
 2004-03-30  Zack Weinberg  <zack@codesourcery.com>
 
        * name-lookup.c, parser.c: Use new shorter form of GTY markers.
index 0b802ff7578f6eb9678d9788e16511623cf4d6b0..ce530fa47093a7b1054ef0e6156d21b59fa1bff6 100644 (file)
@@ -3788,8 +3788,6 @@ start_decl_1 (tree decl)
   if (type == error_mark_node)
     return;
 
-  maybe_push_cleanup_level (type);
-
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
        If not, set INITIALIZED to zero, which will indirectly
@@ -3845,6 +3843,14 @@ start_decl_1 (tree decl)
 
   if (! initialized)
     DECL_INITIAL (decl) = NULL_TREE;
+
+  /* Create a new scope to hold this declaration if necessary.
+     Whether or not a new scope is necessary cannot be determined
+     until after the type has been completed; if the type is a
+     specialization of a class template it is not until after
+     instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+     will be set correctly.  */
+  maybe_push_cleanup_level (type);
 }
 
 /* Handle initialization of references.  DECL, TYPE, and INIT have the
index 3e3d0e91f5d16059ff232269e344466659a05a56..b096017430e656dc2c81815788c56cfaeb741ee4 100644 (file)
@@ -5902,6 +5902,10 @@ tsubst_default_argument (tree fn, tree type, tree arg)
 
   /* FN is already the desired FUNCTION_DECL.  */
   push_access_scope (fn);
+  /* The default argument expression should not be considered to be
+     within the scope of FN.  Since push_access_scope sets
+     current_function_decl, we must explicitly clear it here.  */
+  current_function_decl = NULL_TREE;
 
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
                     tf_error | tf_warning, NULL_TREE);
index 6bba3d51dc91d22562f1cdff8e6dfd31f5b48eda..416128f53c81f9bee083a37241e360f7942f36a8 100644 (file)
@@ -1,3 +1,11 @@
+2004-03-30  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/14724
+       * g++.dg/init/goto1.C: New test.
+
+       PR c++/14763
+       * g++.dg/template/defarg4.C: New test.
+
 2004-03-30  Hartmut Penner  <hpenner@de.ibm.com>
 
        * gcc.dg/altivec-11.c: Extend test for more valid cases.
diff --git a/gcc/testsuite/g++.dg/init/goto1.C b/gcc/testsuite/g++.dg/init/goto1.C
new file mode 100644 (file)
index 0000000..b0a0c52
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/14724
+// { dg-do run }
+
+int j;
+
+template <class T>
+struct C {
+  C() { ++j; }
+  ~C() { --j; }
+};
+
+int main(int, char **) {
+  {
+    int i = 0;
+ again:
+    C<int> v;
+    if (++i < 10)
+      goto again;
+  }
+
+  return j;
+}
+
diff --git a/gcc/testsuite/g++.dg/template/defarg4.C b/gcc/testsuite/g++.dg/template/defarg4.C
new file mode 100644 (file)
index 0000000..293538a
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/14763
+
+struct A { 
+  int get() const {} 
+  static A *foo(); 
+}; 
+template<bool> struct S { 
+  S(unsigned int = A::foo()->get())  ; 
+}; 
+void foo() throw() { 
+  S<false> f; 
+}