Commit 271e6f02 by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/87 (member template assignment operator)

cp:
	PR g++/87
	* cp-tree.h (DECL_COPY_CONSTRUCTOR_P): Use copy_fn_p.
	(copy_args_p): Rename to ...
	(copy_fn_p): ... here.
	(grok_special_member_properties): New function.
	(grok_op_properties): Lose VIRTUALP parameter.
	(copy_assignment_arg_p): Remove.
	* call.c (build_over_call): Use copy_fn_p.
	* decl.c (grokfndecl): Reformat. Adjust call to
	grok_op_properties.
	(copy_args_p): Rename to ...
	(copy_fn_p): ... here. Reject template functions. Check for pass
	by value.
	(grok_special_member_properties): Remember special functions.
	(grok_ctor_properties): Don't remember them here, just check.
	(grok_op_properties): Likewise.
	(start_method): Call grok_special_member_properties.
	* decl2.c (grokfield): Likewise.
	(copy_assignment_arg_p): Remove.
	(grok_function_init): Don't remember abstract assignment here.
	* pt.c (instantiate_class_template): Call
	grok_special_member_properties.
	(tsubst_decl): Adjust grok_op_properties call.
testsuite:
	* g++.dg/other/copy1.C: New test.

From-SVN: r47813
parent b3656137
2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
PR g++/87
* cp-tree.h (DECL_COPY_CONSTRUCTOR_P): Use copy_fn_p.
(copy_args_p): Rename to ...
(copy_fn_p): ... here.
(grok_special_member_properties): New function.
(grok_op_properties): Lose VIRTUALP parameter.
(copy_assignment_arg_p): Remove.
* call.c (build_over_call): Use copy_fn_p.
* decl.c (grokfndecl): Reformat. Adjust call to
grok_op_properties.
(copy_args_p): Rename to ...
(copy_fn_p): ... here. Reject template functions. Check for pass
by value.
(grok_special_member_properties): Remember special functions.
(grok_ctor_properties): Don't remember them here, just check.
(grok_op_properties): Likewise.
(start_method): Call grok_special_member_properties.
* decl2.c (grokfield): Likewise.
(copy_assignment_arg_p): Remove.
(grok_function_init): Don't remember abstract assignment here.
* pt.c (instantiate_class_template): Call
grok_special_member_properties.
(tsubst_decl): Adjust grok_op_properties call.
2001-12-08 Aldy Hernandez <aldyh@redhat.com>
* lex.c (rid_to_yy): Add RID_CHOOSE_EXPR and
......
......@@ -4280,7 +4280,7 @@ build_over_call (cand, args, flags)
}
}
else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
&& copy_args_p (fn)
&& copy_fn_p (fn)
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
{
tree to = stabilize_reference
......
......@@ -1841,7 +1841,7 @@ struct lang_decl
/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor. */
#define DECL_COPY_CONSTRUCTOR_P(NODE) \
(DECL_CONSTRUCTOR_P (NODE) && copy_args_p (NODE))
(DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0)
/* Nonzero if NODE is a destructor. */
#define DECL_DESTRUCTOR_P(NODE) \
......@@ -3690,9 +3690,10 @@ extern int complete_array_type PARAMS ((tree, tree, int));
extern tree build_ptrmemfunc_type PARAMS ((tree));
/* the grokdeclarator prototype is in decl.h */
extern int parmlist_is_exprlist PARAMS ((tree));
extern int copy_args_p PARAMS ((tree));
extern int copy_fn_p PARAMS ((tree));
extern void grok_special_member_properties PARAMS ((tree));
extern int grok_ctor_properties PARAMS ((tree, tree));
extern void grok_op_properties PARAMS ((tree, int, int));
extern void grok_op_properties PARAMS ((tree, int));
extern tree xref_tag PARAMS ((tree, tree, int));
extern tree xref_tag_from_type PARAMS ((tree, tree, int));
extern void xref_basetypes PARAMS ((tree, tree, tree, tree));
......@@ -3757,7 +3758,6 @@ extern tree grokfield PARAMS ((tree, tree, tree, tree, tree));
extern tree grokbitfield PARAMS ((tree, tree, tree));
extern tree groktypefield PARAMS ((tree, tree));
extern tree grokoptypename PARAMS ((tree, tree));
extern int copy_assignment_arg_p PARAMS ((tree, int));
extern void cplus_decl_attributes PARAMS ((tree *, tree, int));
extern tree constructor_name_full PARAMS ((tree));
extern tree constructor_name PARAMS ((tree));
......
......@@ -1645,6 +1645,9 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
SET_DECL_RTL (value, NULL_RTX);
SET_DECL_ASSEMBLER_NAME (value, get_identifier (asmspec));
}
if (!DECL_FRIEND_P (value))
grok_special_member_properties (value);
cp_finish_decl (value, init, asmspec_tree, flags);
/* Pass friends back this way. */
......@@ -1762,28 +1765,6 @@ grokoptypename (declspecs, declarator)
*/
int
copy_assignment_arg_p (parmtype, virtualp)
tree parmtype;
int virtualp ATTRIBUTE_UNUSED;
{
if (current_class_type == NULL_TREE)
return 0;
if (TREE_CODE (parmtype) == REFERENCE_TYPE)
parmtype = TREE_TYPE (parmtype);
if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type)
#if 0
/* Non-standard hack to support old Booch components. */
|| (! virtualp && DERIVED_FROM_P (parmtype, current_class_type))
#endif
)
return 1;
return 0;
}
static void
grok_function_init (decl, init)
tree decl;
......@@ -1796,17 +1777,7 @@ grok_function_init (decl, init)
if (TREE_CODE (type) == FUNCTION_TYPE)
cp_error ("initializer specified for non-member function `%D'", decl);
else if (integer_zerop (init))
{
DECL_PURE_VIRTUAL_P (decl) = 1;
if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
{
tree parmtype
= TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))));
if (copy_assignment_arg_p (parmtype, 1))
TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1;
}
}
DECL_PURE_VIRTUAL_P (decl) = 1;
else
cp_error ("invalid initializer for virtual method `%D'", decl);
}
......
......@@ -5186,6 +5186,7 @@ instantiate_class_template (type)
{
tree r = tsubst (t, args, /*complain=*/1, NULL_TREE);
set_current_access_from_decl (r);
grok_special_member_properties (r);
finish_member_declaration (r);
}
......@@ -5895,10 +5896,10 @@ tsubst_decl (t, args, type)
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
if (PRIMARY_TEMPLATE_P (gen_tmpl))
clone_function_decl(r, /*update_method_vec_p=*/0);
clone_function_decl (r, /*update_method_vec_p=*/0);
}
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
grok_op_properties (r, DECL_FRIEND_P (r));
}
break;
......
2001-12-09 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/copy1.C: New test.
2001-10-08 Aldy Hernandez <aldyh@redhat.com>
* gcc.c-torture/execute/builtin-types-compatible-p.c: New.
......
// { dg-do run }
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 30 Nov 2001 <nathan@nathan@codesourcery.com>
// PR 87
int assign = 0;
int ctor = 0;
int assignC = 0;
struct A {
int i;
template<class T>
void operator=(const T&) const
{
assign = 1;
}
A () : i (0) {}
template <typename T> A (const T &)
{
ctor = 1;
}
};
struct B : A
{
};
struct C
{
int i;
C (int i_) :i (i_) {}
template <int I>
void operator= (const C &)
{
assignC = 1;
}
};
int main()
{
const A a;
A b;
B c;
b = a;
if (assign)
return 5;
b.i = 100;
c.i = 200;
a = b;
if (!assign)
return 1;
if (a.i)
return 2;
A e (b);
if (ctor)
return 3;
A d (c);
if (!ctor)
return 4;
C c0 (0);
C c1 (1);
c0 = c1;
if (assignC)
return 5;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment