C++ PATCH: PR 14724 and PR 14763
Mark Mitchell
mark@codesourcery.com
Tue Mar 30 23:46:00 GMT 2004
This patch fixes two regressions:
* 14724
This was a wrong-code problem involving labels and template classes
with destructors. The destructors were not run in certain
situations where they should have been.
* 14763
This was an ICE when certain expressions were used as default
arguments in a template class.
Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
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 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.
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1174.2.17
diff -c -5 -p -r1.1174.2.17 decl.c
*** cp/decl.c 21 Mar 2004 17:45:25 -0000 1.1174.2.17
--- cp/decl.c 30 Mar 2004 23:40:27 -0000
*************** start_decl_1 (tree decl)
*** 3852,3863 ****
int initialized = (DECL_INITIAL (decl) != NULL_TREE);
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
tell `cp_finish_decl' to ignore the initializer once it is parsed. */
{
--- 3852,3861 ----
*************** start_decl_1 (tree decl)
*** 3909,3918 ****
--- 3907,3924 ----
}
}
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
same meaning as in cp_finish_decl. *CLEANUP must be NULL on entry,
but will be set to a new CLEANUP_STMT if a temporary is created
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.816.2.21
diff -c -5 -p -r1.816.2.21 pt.c
*** cp/pt.c 20 Mar 2004 00:13:14 -0000 1.816.2.21
--- cp/pt.c 30 Mar 2004 23:40:28 -0000
*************** tsubst_default_argument (tree fn, tree t
*** 5889,5898 ****
--- 5889,5902 ----
very fragile. Fortunately, it will go away when we do 2-phase name
binding properly. */
/* 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);
pop_access_scope (fn);
Index: testsuite/g++.dg/init/goto1.C
===================================================================
RCS file: testsuite/g++.dg/init/goto1.C
diff -N testsuite/g++.dg/init/goto1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/goto1.C 30 Mar 2004 23:40:30 -0000
***************
*** 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;
+ }
+
Index: testsuite/g++.dg/template/defarg4.C
===================================================================
RCS file: testsuite/g++.dg/template/defarg4.C
diff -N testsuite/g++.dg/template/defarg4.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/defarg4.C 30 Mar 2004 23:40:30 -0000
***************
*** 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;
+ }
More information about the Gcc-patches
mailing list