re PR c++/27309 (ICE on invalid constructor definition)
authorMark Mitchell <mark@codesourcery.com>
Tue, 2 May 2006 15:59:50 +0000 (15:59 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 2 May 2006 15:59:50 +0000 (15:59 +0000)
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.
PR c++/27309
* g++.dg/parser/ctor5.C: New test.

From-SVN: r113473

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/ctor5.C [new file with mode: 0644]

index 937d5e80f1530e9af3baffd0db4f3d77b8edba12..803644d87904be4e6bd89d7563eafa44308581e7 100644 (file)
@@ -1,3 +1,16 @@
+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  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/27337
index a7536bb7ce98736f71c9339b809dcb8141784edf..f592fe6805ae867c63e45bf9f25d8e94bc1eb690 100644 (file)
@@ -924,6 +924,9 @@ add_method (tree type, tree method, tree using_decl)
       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 e59bd68af8f8dddbdb96b7163c1999a54e5938bc..40c2120556858429ae484d6166d47c062f41d290 100644 (file)
@@ -7541,12 +7541,9 @@ grokdeclarator (const cp_declarator *declarator,
                        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 (tree decl)
             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 (tree decl)
 
       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 *declspecs,
          fndecl = copy_node (fndecl);
          TREE_CHAIN (fndecl) = NULL_TREE;
        }
-      grok_special_member_properties (fndecl);
     }
 
   finish_decl (fndecl, NULL_TREE, NULL_TREE);
index df85e4cba7b4d4319c2ea96ff3a67797a50c85af..ac85b44eac1b45775839787e31aafb56259d45a9 100644 (file)
@@ -923,8 +923,6 @@ grokfield (const cp_declarator *declarator,
     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 68ec8ab418160eb3a4882fce30a9f85074e11851..ddf79bf8e6609de9c532ac06858baccd908f197d 100644 (file)
@@ -1083,7 +1083,6 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
   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 43efc63a3af6d31a1cabf159b84c7a228677bcd1..7b814aef8b64a160d222d2e25432a01051873485 100644 (file)
@@ -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 eb2eab460c5c46c41dbc55371bef19ef784c9915..9608839ee784d68d584a6dfc92ac022b16bbf616 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/27309
+       * g++.dg/parser/ctor5.C: New test.
+
 2006-05-02  Kazu Hirata  <kazu@codesourcery.com>
 
        PR target/27387
diff --git a/gcc/testsuite/g++.dg/parse/ctor5.C b/gcc/testsuite/g++.dg/parse/ctor5.C
new file mode 100644 (file)
index 0000000..8194585
--- /dev/null
@@ -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;