This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 27309
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 2 May 2006 09:03:18 -0700
- Subject: C++ PATCH: PR 27309
- Reply-to: mark at codesourcery dot com
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;