This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix 87
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org, mark at codesourcery dot com
- Date: Mon, 03 Dec 2001 09:31:42 +0000
- Subject: [C++ PATCH] Fix 87
- Organization: Codesourcery LLC
Hi,
this fixes bug 87 where a templated operator= was mistaken for a
trivial copy assignment operator, leading to incorrect code generation.
Here we had
template <typename T> void A::operator=(T const &) const;
which has all the args for a copy assignment operator, but is const
qualified. The implicit (trivial) copy assignment operator is
A &A::operator (A const &);
which loses in jousting. But, as A does have a trivial copy
assignment and the template instantiation matches it's arguments
we get confused. A similar difficulty cannot occur with the
copy constructor.
booted & tested on i686-pc-linux-gnu, ok for mainline?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-11-30 Nathan Sidwell <nathan@codesourcery.com>
* call.c (build_over_call): Template functions are never
copy assignment operators.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.291
diff -c -3 -p -r1.291 call.c
*** call.c 2001/11/29 17:15:54 1.291
--- call.c 2001/11/30 23:04:34
*************** build_over_call (cand, args, flags)
*** 4281,4287 ****
}
else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
&& copy_args_p (fn)
! && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
{
tree to = stabilize_reference
(build_indirect_ref (TREE_VALUE (converted_args), 0));
--- 4281,4291 ----
}
else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
&& copy_args_p (fn)
! && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn))
! /* A class can have an (implicit) trivial copy assign
! operator, but also contain templated assignment
! operators. */
! && !DECL_TEMPLATE_INFO (fn))
{
tree to = stabilize_reference
(build_indirect_ref (TREE_VALUE (converted_args), 0));
// { 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;
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
{
};
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;
return 0;
}