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 27309


This patch fixes PR c++/27309, an ICE-on-valid regression on mainline.

The problem was that we were setting TYPE_HAS_CONSTRUCTOR for a class
when a constructor was declared, even if that constructor was
sufficiently erroneous that we later threw it away, thus leading to a
class that had TYPE_HAS_CONSTRUCTOR set, but no associated
constructor.

Fixed by moving the setting of TYPE_HAS_CONSTRUCTOR to add_method,
which is the point at which a member function is actually being
recorded as part of a class, and by removing multiple unnecessary
calss to grok_special_member_properties throughout the front end.

Tested on x86_64-unknown-linux-gnu, applied to the mainline.  I wil
apply this to 4.1 if no problems show up.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2006-05-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/27309
	* class.c (add_method): Call grok_special_member_properties.
	* decl.c (grokdeclarator): Don't call it here.
	(copy_fn_p): A TEMPLATE_DECL is never a copy constructor or
	assignment operator.  Set TYPE_HAS_CONSTURCTOR if DECL is a
	constructor.
	(start_method): Don't call grok_special_member_properties.
	* method.c (implicitly_declare_fn): Likewise.
	* pt.c (instantiate_class_template): Likewise.
	* decl2.c (grokfield): Likewise.

2006-05-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/27309
	* g++.dg/parser/ctor5.C: New test.

Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 113398)
+++ gcc/cp/class.c	(working copy)
@@ -924,6 +924,9 @@ add_method (tree type, tree method, tree
       CLASSTYPE_METHOD_VEC (type) = method_vec;
     }
 
+  /* Maintain TYPE_HAS_CONSTRUCTOR, etc.  */
+  grok_special_member_properties (method);
+
   /* Constructors and destructors go in special slots.  */
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
     slot = CLASSTYPE_CONSTRUCTOR_SLOT;
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 113398)
+++ gcc/cp/decl.c	(working copy)
@@ -7541,12 +7541,9 @@ grokdeclarator (const cp_declarator *dec
 			pedwarn ("constructors cannot be declared virtual");
 			virtualp = 0;
 		      }
-		    if (decl_context == FIELD)
-		      {
-			TYPE_HAS_CONSTRUCTOR (ctype) = 1;
-			if (sfk != sfk_constructor)
-			  return NULL_TREE;
-		      }
+		    if (decl_context == FIELD
+			&& sfk != sfk_constructor)
+		      return NULL_TREE;
 		  }
 		if (decl_context == FIELD)
 		  staticp = 0;
@@ -8816,8 +8813,9 @@ copy_fn_p (tree d)
 
   gcc_assert (DECL_FUNCTION_MEMBER_P (d));
 
-  if (DECL_TEMPLATE_INFO (d)
-      && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d)))
+  if (TREE_CODE (d) == TEMPLATE_DECL
+      || (DECL_TEMPLATE_INFO (d)
+	  && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
     /* Instantiations of template member functions are never copy
        functions.  Note that member functions of templated classes are
        represented as template functions internally, and we must
@@ -8859,12 +8857,18 @@ copy_fn_p (tree d)
 
 void grok_special_member_properties (tree decl)
 {
+  tree class_type;
+
   if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
-    ; /* Not special.  */
-  else if (DECL_CONSTRUCTOR_P (decl))
+    return;
+
+  class_type = DECL_CONTEXT (decl);
+  if (DECL_CONSTRUCTOR_P (decl))
     {
       int ctor = copy_fn_p (decl);
 
+      TYPE_HAS_CONSTRUCTOR (class_type) = 1;
+
       if (ctor > 0)
 	{
 	  /* [class.copy]
@@ -8874,12 +8878,12 @@ void grok_special_member_properties (tre
 	     X&, volatile X& or const volatile X&, and either there
 	     are no other parameters or else all other parameters have
 	     default arguments.  */
-	  TYPE_HAS_INIT_REF (DECL_CONTEXT (decl)) = 1;
+	  TYPE_HAS_INIT_REF (class_type) = 1;
 	  if (ctor > 1)
-	    TYPE_HAS_CONST_INIT_REF (DECL_CONTEXT (decl)) = 1;
+	    TYPE_HAS_CONST_INIT_REF (class_type) = 1;
 	}
       else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
-	TYPE_HAS_DEFAULT_CONSTRUCTOR (DECL_CONTEXT (decl)) = 1;
+	TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
     }
   else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
     {
@@ -8893,9 +8897,9 @@ void grok_special_member_properties (tre
 
       if (assop)
 	{
-	  TYPE_HAS_ASSIGN_REF (DECL_CONTEXT (decl)) = 1;
+	  TYPE_HAS_ASSIGN_REF (class_type) = 1;
 	  if (assop != 1)
-	    TYPE_HAS_CONST_ASSIGN_REF (DECL_CONTEXT (decl)) = 1;
+	    TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
 	}
     }
 }
@@ -11203,7 +11207,6 @@ start_method (cp_decl_specifier_seq *dec
 	  fndecl = copy_node (fndecl);
 	  TREE_CHAIN (fndecl) = NULL_TREE;
 	}
-      grok_special_member_properties (fndecl);
     }
 
   finish_decl (fndecl, NULL_TREE, NULL_TREE);
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 113398)
+++ gcc/cp/method.c	(working copy)
@@ -1083,7 +1083,6 @@ implicitly_declare_fn (special_function_
   DECL_ARGUMENTS (fn) = this_parm;
 
   grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
-  grok_special_member_properties (fn);
   set_linkage_according_to_type (type, fn);
   rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
   DECL_IN_AGGR_P (fn) = 1;
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 113399)
+++ gcc/cp/pt.c	(working copy)
@@ -5702,7 +5702,6 @@ instantiate_class_template (tree type)
 	      if (TREE_CODE (t) == TEMPLATE_DECL)
 		--processing_template_decl;
 	      set_current_access_from_decl (r);
-	      grok_special_member_properties (r);
 	      finish_member_declaration (r);
 	    }
 	  else
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 113399)
+++ gcc/cp/decl2.c	(working copy)
@@ -923,8 +923,6 @@ grokfield (const cp_declarator *declarat
     case  FUNCTION_DECL:
       if (asmspec)
 	set_user_assembler_name (value, asmspec);
-      if (!DECL_FRIEND_P (value))
-	grok_special_member_properties (value);
 
       cp_finish_decl (value, init, /*init_const_expr_p=*/false, 
 		      asmspec_tree, flags);
Index: gcc/testsuite/g++.dg/parse/ctor5.C
===================================================================
--- gcc/testsuite/g++.dg/parse/ctor5.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/ctor5.C	(revision 0)
@@ -0,0 +1,14 @@
+// PR c++/27309
+
+struct A
+{
+  int i;
+  A() i() {}  // { dg-error "expected" }
+}; // { dg-error "expected" }
+
+struct B
+{
+  A a;
+};
+
+B b;


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