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