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]: name lookup fix


Hi,
this patch fixes a name lookup issue. In a template definition, when 'i'
refers to a field of a non-dependent base, the expression is non-dependent,
and should not be looked up again at instantiation time.

booted & tested on i686-pc-linux-gnu, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2003-07-16  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (finish_non_static_data_member): Add object param.
	* method.c (hack_identifier): Adjust.
	* pt.c (tsubst_copy_and_build) <COMPONENT_REF case>: Don't search
	again for a FIELD_DECL.
	* semantics.c (finish_non_static_data_member): Add object
	parameter. Always save the DECL in the COMPONENT_REF.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.877
diff -c -3 -p -r1.877 cp-tree.h
*** cp/cp-tree.h	14 Jul 2003 19:05:01 -0000	1.877
--- cp/cp-tree.h	16 Jul 2003 16:54:21 -0000
*************** extern tree finish_label_stmt           
*** 4126,4132 ****
  extern void finish_label_decl                   (tree);
  extern void finish_subobject                    (tree);
  extern tree finish_parenthesized_expr           (tree);
! extern tree finish_non_static_data_member       (tree, tree);
  extern tree begin_stmt_expr                     (void);
  extern tree finish_stmt_expr                    (tree);
  extern tree perform_koenig_lookup               (tree, tree);
--- 4127,4133 ----
  extern void finish_label_decl                   (tree);
  extern void finish_subobject                    (tree);
  extern tree finish_parenthesized_expr           (tree);
! extern tree finish_non_static_data_member       (tree, tree, tree);
  extern tree begin_stmt_expr                     (void);
  extern tree finish_stmt_expr                    (tree);
  extern tree perform_koenig_lookup               (tree, tree);
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.260
diff -c -3 -p -r1.260 method.c
*** cp/method.c	8 Jul 2003 01:38:44 -0000	1.260
--- cp/method.c	16 Jul 2003 16:54:23 -0000
*************** hack_identifier (tree value, tree name)
*** 117,123 ****
  
    type = TREE_TYPE (value);
    if (TREE_CODE (value) == FIELD_DECL)
!     value = finish_non_static_data_member (value, 
  					   /*qualifying_scope=*/NULL_TREE);
    else if ((TREE_CODE (value) == FUNCTION_DECL
  	    && DECL_FUNCTION_MEMBER_P (value))
--- 117,123 ----
  
    type = TREE_TYPE (value);
    if (TREE_CODE (value) == FIELD_DECL)
!     value = finish_non_static_data_member (value, current_class_ref,
  					   /*qualifying_scope=*/NULL_TREE);
    else if ((TREE_CODE (value) == FUNCTION_DECL
  	    && DECL_FUNCTION_MEMBER_P (value))
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.726
diff -c -3 -p -r1.726 pt.c
*** cp/pt.c	14 Jul 2003 21:32:25 -0000	1.726
--- cp/pt.c	16 Jul 2003 16:55:19 -0000
*************** tsubst_copy_and_build (tree t, 
*** 8291,8296 ****
--- 8291,8298 ----
  		return error_mark_node;
  	      }
  	  }
+ 	else if (TREE_CODE (member) == FIELD_DECL)
+ 	  return finish_non_static_data_member (member, object, NULL_TREE);
  
  	return finish_class_member_access_expr (object, member);
        }
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.327
diff -c -3 -p -r1.327 semantics.c
*** cp/semantics.c	14 Jul 2003 19:05:02 -0000	1.327
--- cp/semantics.c	16 Jul 2003 16:55:25 -0000
*************** finish_parenthesized_expr (tree expr)
*** 1218,1228 ****
     preceded by `.' or `->'.  */
  
  tree
! finish_non_static_data_member (tree decl, tree qualifying_scope)
  {
    my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
  
!   if (current_class_ptr == NULL_TREE)
      {
        if (current_function_decl 
  	  && DECL_STATIC_FUNCTION_P (current_function_decl))
--- 1218,1228 ----
     preceded by `.' or `->'.  */
  
  tree
! finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
  {
    my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
  
!   if (!object)
      {
        if (current_function_decl 
  	  && DECL_STATIC_FUNCTION_P (current_function_decl))
*************** finish_non_static_data_member (tree decl
*** 1236,1262 ****
      }
    TREE_USED (current_class_ptr) = 1;
    if (processing_template_decl)
-     return build_min (COMPONENT_REF, TREE_TYPE (decl),
- 		      current_class_ref, DECL_NAME (decl));
-   else
      {
!       tree access_type = current_class_type;
!       tree object = current_class_ref;
  
!       while (access_type
! 	     && !DERIVED_FROM_P (context_for_name_lookup (decl), access_type))
  	{
  	  access_type = TYPE_CONTEXT (access_type);
  	  while (access_type && DECL_P (access_type))
  	    access_type = DECL_CONTEXT (access_type);
- 	}
  
!       if (!access_type)
! 	{
! 	  cp_error_at ("object missing in reference to `%D'",
! 		       decl);
! 	  error ("from this location");
! 	  return error_mark_node;
  	}
  
        perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
--- 1236,1271 ----
      }
    TREE_USED (current_class_ptr) = 1;
    if (processing_template_decl)
      {
!       tree type = TREE_TYPE (decl);
! 
!       if (TREE_CODE (type) == REFERENCE_TYPE)
! 	type = TREE_TYPE (type);
!       else if (!DECL_MUTABLE_P (decl))
! 	/* Set the cv qualifiers */
! 	type = cp_build_qualified_type
! 	  (type, (cp_type_quals (TREE_TYPE (current_class_ref))
! 		  | cp_type_quals (TREE_TYPE (decl))));
  
!       return build_min (COMPONENT_REF, type, object, decl);
!     }
!   else
!     {
!       tree access_type = TREE_TYPE (object);
!       tree lookup_context = context_for_name_lookup (decl);
!       
!       while (!DERIVED_FROM_P (lookup_context, access_type))
  	{
  	  access_type = TYPE_CONTEXT (access_type);
  	  while (access_type && DECL_P (access_type))
  	    access_type = DECL_CONTEXT (access_type);
  
! 	  if (!access_type)
! 	    {
! 	      cp_error_at ("object missing in reference to `%D'", decl);
! 	      error ("from this location");
! 	      return error_mark_node;
! 	    }
  	}
  
        perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
*************** finish_qualified_id_expr (tree qualifyin
*** 1357,1363 ****
      }
  
    if (TREE_CODE (expr) == FIELD_DECL)
!     expr = finish_non_static_data_member (expr, qualifying_class);
    else if (BASELINK_P (expr) && !processing_template_decl)
      {
        tree fn;
--- 1366,1373 ----
      }
  
    if (TREE_CODE (expr) == FIELD_DECL)
!     expr = finish_non_static_data_member (expr, current_class_ref,
! 					  qualifying_class);
    else if (BASELINK_P (expr) && !processing_template_decl)
      {
        tree fn;
// { dg-do compile }

// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 16 Jul 2003 <nathan@codesourcery.com>

// A non-dependent field_decl can bind at parse time.

template <class T>
struct Foo {
  int j; // we never see this one.
  int k; // { dg-error "" "" }
  
};

struct Baz 
{
  int j;
  int k; // { dg-error "" "" }
  
};

template <class T>
struct Bar : public Foo<T>, Baz {
  
  int baz () { return j; } // binds to Baz::j
  int foo () { return this->k; } // { dg-error "request for member" "" }
};

int main()
{
  Bar<int> bar;

  bar.baz ();
  bar.foo ();
  
  return 0;
}

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