aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-03-30 23:45:00 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-03-30 23:45:00 +0000
commitc6671cbbbc4bccc110b26c24a3eb706f596b7960 (patch)
tree04761024ef3f5044d3fc69d185c9e2024ebf24a9 /gcc
parent06ce772609f34249723fe45a49d9681827101aac (diff)
downloadgcc-c6671cbbbc4bccc110b26c24a3eb706f596b7960.zip
gcc-c6671cbbbc4bccc110b26c24a3eb706f596b7960.tar.gz
gcc-c6671cbbbc4bccc110b26c24a3eb706f596b7960.tar.bz2
re PR c++/14724 (Destructor not called on backwards goto past initialization)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl.c10
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/init/goto1.C23
-rw-r--r--gcc/testsuite/g++.dg/template/defarg4.C14
6 files changed, 66 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6e3f71a..6fba605 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0b802ff..ce530fa 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3e3d0e9..b096017 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6bba3d5..416128f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..b0a0c52
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/goto1.C
@@ -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
index 0000000..293538a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/defarg4.C
@@ -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;
+}