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 19244


This patch fixes PR c++/19244, a regression involving declarations of
functions in an anonymous class that happen to have the same name
given the class for linkage purposes.  (I think Matt's been running
testsuites....) 

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

2005-01-06  Mark Mitchell  <mark@codesourcery.com>

	PR c++/19244
	* class.c (add_implicitly_declared_members): Remove dead code.
	* decl.c (grokfndecl): Add sfk parameter.  Use it do set
	DECL_CONSTRUCTOR_P.
	(grokdeclarator): Adjust calls to grokfndecl.
	* method.c (implicitly_declare_fn): Improve documentation.
	* parser.c (cp_parser_direct_declarator): Do not consider a
	function to be a constructor if the containing class was
	originally anonymous.

2005-01-06  Mark Mitchell  <mark@codesourcery.com>

        PR c++/19244
	* g++.dg/parser/ctor2.C: New test.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.698
diff -c -5 -p -r1.698 class.c
*** cp/class.c	1 Jan 2005 01:43:12 -0000	1.698
--- cp/class.c	6 Jan 2005 20:12:37 -0000
*************** add_implicitly_declared_members (tree t,
*** 2483,2503 ****
    if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t))
      {
        default_fn = implicitly_declare_fn (sfk_destructor, t, /*const_p=*/0);
        check_for_override (default_fn, t);
  
!       /* If we couldn't make it work, then pretend we didn't need it.  */
!       if (default_fn == void_type_node)
! 	TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 0;
!       else
! 	{
! 	  TREE_CHAIN (default_fn) = implicit_fns;
! 	  implicit_fns = default_fn;
! 
! 	  if (DECL_VINDEX (default_fn))
! 	    virtual_dtor = default_fn;
! 	}
      }
    else
      /* Any non-implicit destructor is non-trivial.  */
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
  
--- 2483,2497 ----
    if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t))
      {
        default_fn = implicitly_declare_fn (sfk_destructor, t, /*const_p=*/0);
        check_for_override (default_fn, t);
  
!       TREE_CHAIN (default_fn) = implicit_fns;
!       implicit_fns = default_fn;
!       
!       if (DECL_VINDEX (default_fn))
! 	virtual_dtor = default_fn;
      }
    else
      /* Any non-implicit destructor is non-trivial.  */
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
  
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1351
diff -c -5 -p -r1.1351 decl.c
*** cp/decl.c	5 Jan 2005 10:02:03 -0000	1.1351
--- cp/decl.c	6 Jan 2005 20:12:38 -0000
*************** static int decl_jump_unsafe (tree);
*** 59,72 ****
  static void require_complete_types_for_parms (tree);
  static int ambi_op_p (enum tree_code);
  static int unary_op_p (enum tree_code);
  static void push_local_name (tree);
  static tree grok_reference_init (tree, tree, tree, tree *);
- static tree grokfndecl (tree, tree, tree, tree, tree, int,
- 			enum overload_flags, cp_cv_quals,
- 			tree, int, int, int, int, int, int, tree, 
- 			tree *);
  static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
  			 int, int, tree);
  static void record_unknown_type (tree, const char *);
  static tree builtin_function_1 (const char *, tree, tree,
  				enum built_in_function code,
--- 59,68 ----
*************** grokfndecl (tree ctype,
*** 5631,5640 ****
--- 5627,5637 ----
              tree raises,
              int check,
              int friendp,
              int publicp,
              int inlinep,
+ 	    special_function_kind sfk,
              int funcdef_flag,
              int template_count,
              tree in_namespace,
  	    tree* attrlist)
  {
*************** grokfndecl (tree ctype,
*** 5841,5858 ****
  
    /* Caller will do the rest of this.  */
    if (check < 0)
      return decl;
  
-   if (flags == NO_SPECIAL && ctype && constructor_name_p (declarator, ctype))
-     DECL_CONSTRUCTOR_P (decl) = 1;
- 
-   /* Function gets the ugly name, field gets the nice one.  This call
-      may change the type of the function (because of default
-      parameters)!  */
    if (ctype != NULL_TREE)
!     grokclassfn (ctype, decl, flags, quals);
  
    decl = check_explicit_specialization (orig_declarator, decl,
  					template_count,
  					2 * (funcdef_flag != 0) +
  					4 * (friendp != 0));
--- 5838,5854 ----
  
    /* Caller will do the rest of this.  */
    if (check < 0)
      return decl;
  
    if (ctype != NULL_TREE)
!     {
!       if (sfk == sfk_constructor)
! 	DECL_CONSTRUCTOR_P (decl) = 1;
! 
!       grokclassfn (ctype, decl, flags, quals);
!     }
  
    decl = check_explicit_specialization (orig_declarator, decl,
  					template_count,
  					2 * (funcdef_flag != 0) +
  					4 * (friendp != 0));
*************** grokdeclarator (const cp_declarator *dec
*** 7979,7988 ****
--- 7975,7985 ----
  			       ? unqualified_id : dname,
  			       parms,
  			       unqualified_id,
  			       virtualp, flags, quals, raises,
  			       friendp ? -1 : 0, friendp, publicp, inlinep,
+ 			       sfk,
  			       funcdef_flag, template_count, in_namespace, attrlist);
  	    if (decl == NULL_TREE)
  	      return decl;
  #if 0
  	    /* This clobbers the attrs stored in `decl' from `attrlist'.  */
*************** grokdeclarator (const cp_declarator *dec
*** 8025,8036 ****
  			       TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
  			       ? unqualified_id : dname,
  			       parms,
  			       unqualified_id,
  			       virtualp, flags, quals, raises,
! 			       friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
! 			       template_count, in_namespace, attrlist);
  	    if (decl == NULL_TREE)
  	      return NULL_TREE;
  	  }
  	else if (!staticp && !dependent_type_p (type)
  		 && !COMPLETE_TYPE_P (complete_type (type))
--- 8022,8034 ----
  			       TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
  			       ? unqualified_id : dname,
  			       parms,
  			       unqualified_id,
  			       virtualp, flags, quals, raises,
! 			       friendp ? -1 : 0, friendp, 1, 0, sfk,
! 			       funcdef_flag, template_count, in_namespace, 
! 			       attrlist); 
  	    if (decl == NULL_TREE)
  	      return NULL_TREE;
  	  }
  	else if (!staticp && !dependent_type_p (type)
  		 && !COMPLETE_TYPE_P (complete_type (type))
*************** grokdeclarator (const cp_declarator *dec
*** 8211,8221 ****
  		   || storage_class != sc_static);
  
  	decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
  			   virtualp, flags, quals, raises,
  			   1, friendp,
! 			   publicp, inlinep, funcdef_flag,
  			   template_count, in_namespace, attrlist);
  	if (decl == NULL_TREE)
  	  return NULL_TREE;
  
  	if (staticp == 1)
--- 8209,8219 ----
  		   || storage_class != sc_static);
  
  	decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
  			   virtualp, flags, quals, raises,
  			   1, friendp,
! 			   publicp, inlinep, sfk, funcdef_flag,
  			   template_count, in_namespace, attrlist);
  	if (decl == NULL_TREE)
  	  return NULL_TREE;
  
  	if (staticp == 1)
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.318
diff -c -5 -p -r1.318 method.c
*** cp/method.c	21 Dec 2004 17:28:34 -0000	1.318
--- cp/method.c	6 Jan 2005 20:12:38 -0000
*************** locate_copy (tree type, void *client_)
*** 923,933 ****
  }
  
  /* Implicitly declare the special function indicated by KIND, as a
     member of TYPE.  For copy constructors and assignment operators,
     CONST_P indicates whether these functions should take a const
!    reference argument or a non-const reference.  */
  
  tree
  implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
  {
    tree fn;
--- 923,934 ----
  }
  
  /* Implicitly declare the special function indicated by KIND, as a
     member of TYPE.  For copy constructors and assignment operators,
     CONST_P indicates whether these functions should take a const
!    reference argument or a non-const reference.  Returns the
!    FUNCTION_DECL for the implicitly declared function.  */
  
  tree
  implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
  {
    tree fn;
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.301
diff -c -5 -p -r1.301 parser.c
*** cp/parser.c	5 Jan 2005 10:02:16 -0000	1.301
--- cp/parser.c	6 Jan 2005 20:12:38 -0000
*************** cp_parser_direct_declarator (cp_parser* 
*** 11107,11121 ****
  		{
  		  if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
  		    declarator->u.id.sfk = sfk_destructor;
  		  else if (IDENTIFIER_TYPENAME_P (unqualified_name))
  		    declarator->u.id.sfk = sfk_conversion;
! 		  else if (constructor_name_p (unqualified_name,
! 					       class_type)
! 			   || (TREE_CODE (unqualified_name) == TYPE_DECL
! 			       && same_type_p (TREE_TYPE (unqualified_name),
! 					       class_type)))
  		    declarator->u.id.sfk = sfk_constructor;
  
  		  if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
  		    *ctor_dtor_or_conv_p = -1;
  		  if (qualifying_scope
--- 11107,11126 ----
  		{
  		  if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
  		    declarator->u.id.sfk = sfk_destructor;
  		  else if (IDENTIFIER_TYPENAME_P (unqualified_name))
  		    declarator->u.id.sfk = sfk_conversion;
! 		  else if (/* There's no way to declare a constructor
! 			      for an anonymous type, even if the type
! 			      got a name for linkage purposes.  */
! 			   !TYPE_WAS_ANONYMOUS (class_type)
! 			   && (constructor_name_p (unqualified_name,
! 						   class_type)
! 			       || (TREE_CODE (unqualified_name) == TYPE_DECL
! 				   && (same_type_p 
! 				       (TREE_TYPE (unqualified_name),
! 					class_type)))))
  		    declarator->u.id.sfk = sfk_constructor;
  
  		  if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
  		    *ctor_dtor_or_conv_p = -1;
  		  if (qualifying_scope
Index: testsuite/g++.dg/parse/ctor2.C
===================================================================
RCS file: testsuite/g++.dg/parse/ctor2.C
diff -N testsuite/g++.dg/parse/ctor2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/ctor2.C	6 Jan 2005 20:12:38 -0000
***************
*** 0 ****
--- 1,4 ----
+ // PR c++/19244
+ 
+ typedef struct { void f(); } f;
+ void f::f() { }



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