This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 16623


This patch fixes PR c++/16623, a regression caused by my lazy
assignment operator patch.  This makes the handling of assignment
operators more consistent with implicitly defined constructors.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-07-19  Mark Mitchell  <mark@codesourcery.com>

	PR c++/16623
	* cp-tree.h (lang_type_class): Add lazy_assignment_op.
	(CLASSTYPE_LAZY_ASSIGNMENT_OP): New macro.
	* class.c (add_implicitly_declared_members): Use
	CLASSTYPE_LAZY_ASSIGNMENT_OP.
	* method.c (lazily_declare_fn): Clear
	CLASSTYPE_LAZY_ASSIGNMENT_OP.
	* search.c (lookup_fnfields_1): Check it.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.637
diff -c -5 -p -r1.637 class.c
*** cp/class.c	17 Jul 2004 07:31:04 -0000	1.637
--- cp/class.c	19 Jul 2004 19:02:26 -0000
*************** add_implicitly_declared_members (tree t,
*** 2562,2572 ****
    /* If there is no assignment operator, one will be created if and
       when it is needed.  For now, just record whether or not the type
       of the parameter to the assignment operator will be a const or
       non-const reference.  */
    if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
!     TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
    
    /* Now, hook all of the new functions on to TYPE_METHODS,
       and add them to the CLASSTYPE_METHOD_VEC.  */
    for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f))
      {
--- 2562,2576 ----
    /* If there is no assignment operator, one will be created if and
       when it is needed.  For now, just record whether or not the type
       of the parameter to the assignment operator will be a const or
       non-const reference.  */
    if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
!     {
!       TYPE_HAS_ASSIGN_REF (t) = 1;
!       TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
!       CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 1;
!     }
    
    /* Now, hook all of the new functions on to TYPE_METHODS,
       and add them to the CLASSTYPE_METHOD_VEC.  */
    for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f))
      {
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1011
diff -c -5 -p -r1.1011 cp-tree.h
*** cp/cp-tree.h	17 Jul 2004 07:31:06 -0000	1.1011
--- cp/cp-tree.h	19 Jul 2004 19:02:27 -0000
*************** struct lang_type_class GTY(())
*** 991,1000 ****
--- 991,1001 ----
    unsigned ptrmemfunc_flag : 1;
    unsigned was_anonymous : 1;
  
    unsigned lazy_default_ctor : 1;
    unsigned lazy_copy_ctor : 1;
+   unsigned lazy_assignment_op : 1;
    unsigned has_const_init_ref : 1;
    unsigned has_complex_init_ref : 1;
    unsigned has_complex_assign_ref : 1;
    unsigned non_aggregate : 1;
    unsigned java_interface : 1;
*************** struct lang_type_class GTY(())
*** 1004,1014 ****
       so, make sure to copy it in instantiate_class_template!  */
  
    /* There are some bits left to fill out a 32-bit word.  Keep track
       of this by updating the size of this bitfield whenever you add or
       remove a flag.  */
!   unsigned dummy : 9;
  
    tree primary_base;
    tree vfields;
    tree vcall_indices;
    tree vtables;
--- 1005,1015 ----
       so, make sure to copy it in instantiate_class_template!  */
  
    /* There are some bits left to fill out a 32-bit word.  Keep track
       of this by updating the size of this bitfield whenever you add or
       remove a flag.  */
!   unsigned dummy : 8;
  
    tree primary_base;
    tree vfields;
    tree vcall_indices;
    tree vtables;
*************** struct lang_type GTY(())
*** 1099,1108 ****
--- 1100,1114 ----
  /* Nonzero means that NODE (a class type) has a copy constructor --
     but that it has not yet been declared.  */
  #define CLASSTYPE_LAZY_COPY_CTOR(NODE) \
    (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_ctor)
  
+ /* Nonzero means that NODE (a class type) has an assignment operator
+    -- but that it has not yet been declared.  */
+ #define CLASSTYPE_LAZY_ASSIGNMENT_OP(NODE) \
+   (LANG_TYPE_CLASS_CHECK (NODE)->lazy_assignment_op)
+ 
  /* Nonzero means that this _CLASSTYPE node overloads operator=(X&).  */
  #define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref)
  
  /* True iff the class type NODE has an "operator =" whose parameter
     has a parameter of type "const X&".  */
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.298
diff -c -5 -p -r1.298 method.c
*** cp/method.c	17 Jul 2004 07:31:08 -0000	1.298
--- cp/method.c	19 Jul 2004 19:02:27 -0000
*************** lazily_declare_fn (special_function_kind
*** 1066,1075 ****
--- 1066,1077 ----
        else
  	CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
        /* Create appropriate clones.  */
        clone_function_decl (fn, /*update_method_vec=*/true);
      }
+   else if (sfk == sfk_assignment_operator)
+     CLASSTYPE_LAZY_ASSIGNMENT_OP (type) = 0;
  
    return fn;
  }
  
  /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.302
diff -c -5 -p -r1.302 search.c
*** cp/search.c	17 Jul 2004 07:31:08 -0000	1.302
--- cp/search.c	19 Jul 2004 19:02:27 -0000
*************** lookup_fnfields_1 (tree type, tree name)
*** 1378,1389 ****
  	    lazily_declare_fn (sfk_constructor, type);
  	  if (CLASSTYPE_LAZY_COPY_CTOR (type))
  	    lazily_declare_fn (sfk_copy_constructor, type);
  	}
        else if (name == ansi_assopname(NOP_EXPR)
! 	       && !TYPE_HAS_ASSIGN_REF (type)
! 	       && !TYPE_FOR_JAVA (type))
  	lazily_declare_fn (sfk_assignment_operator, type);
      }
  
    method_vec = CLASSTYPE_METHOD_VEC (type);
    if (!method_vec)
--- 1378,1388 ----
  	    lazily_declare_fn (sfk_constructor, type);
  	  if (CLASSTYPE_LAZY_COPY_CTOR (type))
  	    lazily_declare_fn (sfk_copy_constructor, type);
  	}
        else if (name == ansi_assopname(NOP_EXPR)
! 	       && CLASSTYPE_LAZY_ASSIGNMENT_OP (type))
  	lazily_declare_fn (sfk_assignment_operator, type);
      }
  
    method_vec = CLASSTYPE_METHOD_VEC (type);
    if (!method_vec)
Index: testsuite/g++.dg/template/assign1.C
===================================================================
RCS file: testsuite/g++.dg/template/assign1.C
diff -N testsuite/g++.dg/template/assign1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/assign1.C	19 Jul 2004 19:02:27 -0000
***************
*** 0 ****
--- 1,15 ----
+ // PR c++/16623
+ 
+ template <int N>
+ struct C
+ {
+   C& operator= (int);
+ };
+ 
+ template <int N>
+ C<N>& C<N>::operator= (int)
+ {
+   return *this;
+ }
+ 
+ C<0> a;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]