PR 17585, again

Mark Mitchell mark@codesourcery.com
Mon Sep 27 19:22:00 GMT 2004


This patch fixes PR 17585 that does not depend on the order in which
things are declared.  Tested on i686-pc-linux-gnu, applied on the
mainline and on the 3.4 branch.

There is a related standards question here.  Given:

  struct S { 
    static void f(int);
    void f(double);
    void g();
  };

  void S::g() {
    f(3);
  }

does:

  [class.mfct.nonstatic]

  When an id-expression (_expr.prim_) that is not part of a class
  member access syntax (_expr.ref_) and not used to form a pointer to
  member (_expr.unary.op_) is used in the body of a nonstatic member
  function of class X or used in the mem-initializer for a constructor
  of class X, if name lookup (_basic.lookup.unqual_) resolves the name
  in the id- expression to a nonstatic nontype member of class X or of
  a base class of X, the id-expression is transformed into a class
  member access expression (_expr.ref_) using (*this) (_class.this_)
  as the postfix-expression to the left of the .  operator

apply?  Is that supposed to apply only after overload resolution?
Also, what about the fact that "this->f" is not a valid template
argument, even if "f" is static, while plain "f" is valid?  Is the
transformation required here supposed to apply before we determine
whether or not the template argument is valid, or not?

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-09-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/17585
	* cp-tree.h (shared_member_p): Declare.
	* search.c (shared_member_p): Give it external linkage.
	* semantics.c (finish_qualified_id_expr): Use it.
	(finish_id_expression): Likewise.

Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1053
diff -c -5 -p -r1.1053 cp-tree.h
*** cp-tree.h	27 Sep 2004 12:00:07 -0000	1.1053
--- cp-tree.h	27 Sep 2004 18:46:31 -0000
*************** extern tree binfo_via_virtual           
*** 4021,4030 ****
--- 4021,4031 ----
  extern tree build_baselink                      (tree, tree, tree, tree);
  extern tree adjust_result_of_qualified_name_lookup
                                                  (tree, tree, tree);
  extern tree copied_binfo			(tree, tree);
  extern tree original_binfo			(tree, tree);
+ extern int shared_member_p                      (tree);
  
  /* in semantics.c */
  extern void push_deferring_access_checks	(deferring_kind);
  extern void resume_deferring_access_checks	(void);
  extern void stop_deferring_access_checks	(void);
Index: search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.323
diff -c -5 -p -r1.323 search.c
*** search.c	27 Sep 2004 12:00:08 -0000	1.323
--- search.c	27 Sep 2004 18:46:31 -0000
*************** static int check_hidden_convs (tree, int
*** 54,64 ****
  static tree split_conversions (tree, tree, tree, tree);
  static int lookup_conversions_r (tree, int, int,
  				 tree, tree, tree, tree, tree *, tree *);
  static int look_for_overrides_r (tree, tree);
  static tree lookup_field_queue_p (tree, int, void *);
- static int shared_member_p (tree);
  static tree lookup_field_r (tree, void *);
  static tree dfs_accessible_queue_p (tree, int, void *);
  static tree dfs_accessible_p (tree, void *);
  static tree dfs_access_in_type (tree, void *);
  static access_kind access_in_type (tree, tree);
--- 54,63 ----
*************** template_self_reference_p (tree type, tr
*** 1023,1033 ****
     and  includes members from distinct sub-objects, there is an ambiguity
     and the program is ill-formed.
  
     This function checks that T contains no nonstatic members.  */
  
! static int
  shared_member_p (tree t)
  {
    if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \
        || TREE_CODE (t) == CONST_DECL)
      return 1;
--- 1022,1032 ----
     and  includes members from distinct sub-objects, there is an ambiguity
     and the program is ill-formed.
  
     This function checks that T contains no nonstatic members.  */
  
! int
  shared_member_p (tree t)
  {
    if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \
        || TREE_CODE (t) == CONST_DECL)
      return 1;
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.439
diff -c -5 -p -r1.439 semantics.c
*** semantics.c	27 Sep 2004 14:46:47 -0000	1.439
--- semantics.c	27 Sep 2004 18:46:31 -0000
*************** finish_qualified_id_expr (tree qualifyin
*** 1424,1446 ****
    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;
        tree fns;
  
        /* See if any of the functions are non-static members.  */
        fns = BASELINK_FUNCTIONS (expr);
        if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
  	fns = TREE_OPERAND (fns, 0);
-       for (fn = fns; fn; fn = OVL_NEXT (fn))
- 	if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
- 	  break;
        /* If so, the expression may be relative to the current
  	 class.  */
!       if (fn && current_class_type 
  	  && DERIVED_FROM_P (qualifying_class, current_class_type))
  	expr = (build_class_member_access_expr 
  		(maybe_dummy_object (qualifying_class, NULL),
  		 expr,
  		 BASELINK_ACCESS_BINFO (expr),
--- 1424,1443 ----
    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 fns;
  
        /* See if any of the functions are non-static members.  */
        fns = BASELINK_FUNCTIONS (expr);
        if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
  	fns = TREE_OPERAND (fns, 0);
        /* If so, the expression may be relative to the current
  	 class.  */
!       if (!shared_member_p (fns)
! 	  && current_class_type 
  	  && DERIVED_FROM_P (qualifying_class, current_class_type))
  	expr = (build_class_member_access_expr 
  		(maybe_dummy_object (qualifying_class, NULL),
  		 expr,
  		 BASELINK_ACCESS_BINFO (expr),
*************** finish_id_expression (tree id_expression
*** 2644,2654 ****
  
  	  if (!really_overloaded_fn (decl))
  	    mark_used (first_fn);
  
  	  if (TREE_CODE (first_fn) == FUNCTION_DECL
! 	      && DECL_NONSTATIC_MEMBER_FUNCTION_P (first_fn))
  	    {
  	      /* A set of member functions.  */
  	      decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
  	      return finish_class_member_access_expr (decl, id_expression);
  	    }
--- 2641,2652 ----
  
  	  if (!really_overloaded_fn (decl))
  	    mark_used (first_fn);
  
  	  if (TREE_CODE (first_fn) == FUNCTION_DECL
! 	      && DECL_FUNCTION_MEMBER_P (first_fn)
! 	      && !shared_member_p (decl))
  	    {
  	      /* A set of member functions.  */
  	      decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
  	      return finish_class_member_access_expr (decl, id_expression);
  	    }



More information about the Gcc-patches mailing list