This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix bug 5116
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Mon, 31 Dec 2001 16:37:00 +0000
- Subject: [C++ PATCH] Fix bug 5116
- Organization: Codesourcery LLC
Hi,
this fixes bug 5116 where we failed to find a friend operator. I believe
that, if the operands to an operator have templated class type, they
should be instantiated at that point, because their instantiation can
affect the meaning of the program.
built & tested on i686-pc-linux-gnu, ok?
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-12-31 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5116, c++/764
* call.c (build_new_op): Make sure template class operands are
instantiated. Simplify arglist construction.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.300
diff -c -3 -p -r1.300 call.c
*** call.c 2001/12/29 17:24:59 1.300
--- call.c 2001/12/31 15:15:47
*************** build_new_op (code, flags, arg1, arg2, a
*** 3247,3252 ****
--- 3247,3256 ----
if (TREE_CODE (arg1) == OFFSET_REF)
arg1 = resolve_offset_ref (arg1);
arg1 = convert_from_reference (arg1);
+ if (CLASS_TYPE_P (TREE_TYPE (arg1))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg1)))
+ /* Make sure the template type is instantiated now. */
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)));
switch (code)
{
*************** build_new_op (code, flags, arg1, arg2, a
*** 3269,3280 ****
--- 3273,3290 ----
if (TREE_CODE (arg2) == OFFSET_REF)
arg2 = resolve_offset_ref (arg2);
arg2 = convert_from_reference (arg2);
+ if (CLASS_TYPE_P (TREE_TYPE (arg2))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg2)))
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg2)));
}
if (arg3)
{
if (TREE_CODE (arg3) == OFFSET_REF)
arg3 = resolve_offset_ref (arg3);
arg3 = convert_from_reference (arg3);
+ if (CLASS_TYPE_P (TREE_TYPE (arg3))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg3)))
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg3)));
}
if (code == COND_EXPR)
*************** build_new_op (code, flags, arg1, arg2, a
*** 3293,3305 ****
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
arg2 = integer_zero_node;
! if (arg2 && arg3)
! arglist = tree_cons (NULL_TREE, arg1, tree_cons
! (NULL_TREE, arg2, build_tree_list (NULL_TREE, arg3)));
! else if (arg2)
! arglist = tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2));
! else
! arglist = build_tree_list (NULL_TREE, arg1);
fns = lookup_function_nonclass (fnname, arglist);
--- 3303,3314 ----
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
arg2 = integer_zero_node;
! arglist = NULL_TREE;
! if (arg3)
! arglist = tree_cons (NULL_TREE, arg3, arglist);
! if (arg2)
! arglist = tree_cons (NULL_TREE, arg2, arglist);
! arglist = tree_cons (NULL_TREE, arg1, arglist);
fns = lookup_function_nonclass (fnname, arglist);
// { dg-do run }
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com>
// PR 5116 Failed to find friend in overload resolution
int wrong;
int right;
struct Printer
{
Printer &operator<< (bool a)
{
wrong++;
return *this;
}
};
struct Buggy {};
template <typename T> struct Handle
{
Handle(T* p) {}
operator bool() const { return true; }
friend Printer& operator<<(Printer& ostr, const Handle& r)
{
right++;
return ostr;
}
};
typedef Handle<Buggy> Buggy_h;
Printer out;
bool cmp (const Buggy_h& b1, const Buggy_h& b2)
{
out << b1 << b2;
return false;
}
int main()
{
Buggy o;
cmp (&o, &o);
if (wrong)
return 1;
if (right != 2)
return 2;
return 0;
}