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 7964


Hi,
I've installed this patch to fix 7964. In instantiating a scoped method
call, we weren't going via the same path as non templated things. Thus
missing a base conversion.

Mark, this possibly impacts the new parser, you might be doing things
differently there.

booted and tested on i686-pc-linux-gnu. I'll be putting this on the 3.3
branch shortly.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org

2002-12-24  Nathan Sidwell  <nathan@codesourcery.com>

	PR C++/7964
	* cp-tree.h (resolve_scoped_fn_name): Prototype.
	* call.c (resolve_scoped_fn_name): New function. Deal with
	more template expansion. Broken out of ...
	* parse.y (parse_finish_call_expr): ... here. Call it.
	* decl2.c (build_expr_from_tree, CALL_EXPR): Use
	resolve_scoped_fn_name and build_call_from_tree.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.344
diff -c -3 -p -r1.344 call.c
*** cp/call.c	23 Dec 2002 23:44:47 -0000	1.344
--- cp/call.c	24 Dec 2002 22:13:32 -0000
*************** build_user_type_conversion (tree totype,
*** 2597,2602 ****
--- 2597,2665 ----
    return NULL_TREE;
  }
  
+ /* Find the possibly overloaded set of functions corresponding to a
+    call of the form SCOPE::NAME (...). NAME might be a
+    TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */
+ 
+ tree
+ resolve_scoped_fn_name (tree scope, tree name)
+ {
+   tree fn;
+   tree template_args = NULL_TREE;
+   bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR;
+   
+   if (is_template_id)
+     {
+       template_args = TREE_OPERAND (name, 1);
+       name = TREE_OPERAND (name, 0);
+     }
+   if (TREE_CODE (name) == OVERLOAD)
+     name = DECL_NAME (get_first_fn (name));
+   else if (TREE_CODE (name) == LOOKUP_EXPR)
+     name = TREE_OPERAND (name, 0);
+   
+   if (TREE_CODE (scope) == NAMESPACE_DECL)
+     fn = lookup_namespace_name (scope, name);
+   else
+     {
+       if (!TYPE_BEING_DEFINED (scope)
+ 	  && !COMPLETE_TYPE_P (complete_type (scope)))
+ 	{
+ 	  error ("incomplete type '%T' cannot be used to name a scope",
+ 		 scope);
+ 	  return error_mark_node;
+ 	}
+       
+       if (BASELINK_P (name))
+ 	fn = name;
+       else
+ 	fn = lookup_member (scope, name, /*protect=*/1, /*prefer_type=*/0);
+       if (fn && current_class_type)
+ 	fn = (adjust_result_of_qualified_name_lookup 
+ 	      (fn, scope, current_class_type));
+     }
+   
+   if (!fn)
+     {
+       error ("'%D' has no member named '%E'", scope, name);
+       return error_mark_node;
+     }
+   if (is_template_id)
+     {
+       tree fns = fn;
+ 
+       if (BASELINK_P (fn))
+ 	fns = BASELINK_FUNCTIONS (fns);
+       fns = build_nt (TEMPLATE_ID_EXPR, fns, template_args);
+       if (BASELINK_P (fn))
+ 	BASELINK_FUNCTIONS (fn) = fns;
+       else
+ 	fn = fns;
+     }
+   
+   return fn;
+ }
+ 
  /* Do any initial processing on the arguments to a function call.  */
  
  static tree
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.782
diff -c -3 -p -r1.782 cp-tree.h
*** cp/cp-tree.h	23 Dec 2002 23:44:47 -0000	1.782
--- cp/cp-tree.h	24 Dec 2002 22:14:02 -0000
*************** extern tree build_method_call (tree, tre
*** 3547,3552 ****
--- 3547,3553 ----
  extern bool null_ptr_cst_p (tree);
  extern bool sufficient_parms_p (tree);
  extern tree type_decays_to (tree);
+ extern tree resolve_scoped_fn_name (tree, tree);
  extern tree build_user_type_conversion (tree, tree, int);
  extern tree build_new_function_call (tree, tree);
  extern tree build_new_method_call (tree, tree, tree, tree, int);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.579
diff -c -3 -p -r1.579 decl2.c
*** cp/decl2.c	24 Dec 2002 22:12:15 -0000	1.579
--- cp/decl2.c	24 Dec 2002 22:14:20 -0000
*************** build_expr_from_tree (t)
*** 3241,3256 ****
  	{
  	  tree ref = TREE_OPERAND (t, 0);
  	  tree name = TREE_OPERAND (ref, 1);
  	  
  	  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
  	    name = build_nt (TEMPLATE_ID_EXPR,
  	                     TREE_OPERAND (name, 0),
  	                     build_expr_from_tree (TREE_OPERAND (name, 1)));
! 	    
! 	  return build_member_call
! 	    (build_expr_from_tree (TREE_OPERAND (ref, 0)),
! 	     name,
! 	     build_expr_from_tree (TREE_OPERAND (t, 1)));
  	}
        else
  	{
--- 3241,3258 ----
  	{
  	  tree ref = TREE_OPERAND (t, 0);
  	  tree name = TREE_OPERAND (ref, 1);
+ 	  tree fn, scope, args;
  	  
  	  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
  	    name = build_nt (TEMPLATE_ID_EXPR,
  	                     TREE_OPERAND (name, 0),
  	                     build_expr_from_tree (TREE_OPERAND (name, 1)));
! 
! 	  scope = build_expr_from_tree (TREE_OPERAND (ref, 0));
! 	  args = build_expr_from_tree (TREE_OPERAND (t, 1));
! 	  fn = resolve_scoped_fn_name (scope, name);
! 	  
! 	  return build_call_from_tree (fn, args, 1);
  	}
        else
  	{
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.287
diff -c -3 -p -r1.287 parse.y
*** cp/parse.y	22 Dec 2002 21:32:27 -0000	1.287
--- cp/parse.y	24 Dec 2002 22:14:31 -0000
*************** static tree
*** 4115,4186 ****
  parse_finish_call_expr (tree fn, tree args, int koenig)
  {
    bool disallow_virtual;
-   tree template_args;
-   tree template_id;
-   tree f;
  
    if (TREE_CODE (fn) == OFFSET_REF)
      return build_offset_ref_call_from_tree (fn, args);
  
    if (TREE_CODE (fn) == SCOPE_REF)
      {
!       tree scope;
!       tree name;
! 
!       scope = TREE_OPERAND (fn, 0);
!       name = TREE_OPERAND (fn, 1);
  
        if (scope == error_mark_node || name == error_mark_node)
  	return error_mark_node;
        if (!processing_template_decl)
! 	{
! 	  if (TREE_CODE (scope) == NAMESPACE_DECL)
! 	    fn = lookup_namespace_name (scope, name);
! 	  else
! 	    {
! 	      if (!COMPLETE_TYPE_P (scope) && !TYPE_BEING_DEFINED (scope))
! 		{
! 		  error ("incomplete type '%T' cannot be used to name a scope",
! 			 scope);
! 		  return error_mark_node;
! 		}
! 	      else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
! 		{
! 		  template_id = name;
! 		  template_args = TREE_OPERAND (name, 1);
! 		  name = TREE_OPERAND (name, 0);
! 		}
! 	      else 
! 	        {
! 		  template_id = NULL_TREE;
! 		  template_args = NULL_TREE;
! 		}
! 
! 	      if (BASELINK_P (name))
! 		fn = name;
! 	      else 
! 		{
! 		  if (TREE_CODE (name) == OVERLOAD)
! 		    name = DECL_NAME (get_first_fn (name));
! 		  fn = lookup_member (scope, name, /*protect=*/1, 
! 				      /*prefer_type=*/0);
! 		  if (!fn)
! 		    {
! 		      error ("'%D' has no member named '%E'", scope, name);
! 		      return error_mark_node;
! 		    }
! 		  
! 		  if (BASELINK_P (fn) && template_id)
! 		    BASELINK_FUNCTIONS (fn) 
! 		      = build_nt (TEMPLATE_ID_EXPR,
! 				  BASELINK_FUNCTIONS (fn),
! 				  template_args);
! 		}
! 	      if (current_class_type)
! 		fn = (adjust_result_of_qualified_name_lookup 
! 		      (fn, scope, current_class_type));
! 	    }
! 	}
        disallow_virtual = true;
      }
    else
--- 4115,4133 ----
  parse_finish_call_expr (tree fn, tree args, int koenig)
  {
    bool disallow_virtual;
  
    if (TREE_CODE (fn) == OFFSET_REF)
      return build_offset_ref_call_from_tree (fn, args);
  
    if (TREE_CODE (fn) == SCOPE_REF)
      {
!       tree scope = TREE_OPERAND (fn, 0);
!       tree name = TREE_OPERAND (fn, 1);
  
        if (scope == error_mark_node || name == error_mark_node)
  	return error_mark_node;
        if (!processing_template_decl)
! 	fn = resolve_scoped_fn_name (scope, name);
        disallow_virtual = true;
      }
    else
*************** parse_finish_call_expr (tree fn, tree ar
*** 4188,4193 ****
--- 4135,4142 ----
  
    if (koenig && TREE_CODE (fn) == IDENTIFIER_NODE)
      {
+       tree f;
+       
        /* Do the Koenig lookup.  */
        fn = do_identifier (fn, 2, args);
        /* If name lookup didn't find any matching declarations, we've
// { dg-do compile }

// Copyright (C) 2002 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com>

// PR 7964. ICE with scoped method call

struct A {
  virtual void ostr() const;
};

class B : public virtual A {};

template<typename T>
struct C : public B
{
  void ostr() const
  {    B::ostr();  }
};


template C<int>;

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