This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix bug 5116


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]