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]

[C++ PATCH]: Fix ptr to member syntax checking


Hi,

this patch fixes bug 46 about assuming & on overloaded member function.
The problem is that although `&T::m' is the only way to form pointer to
non-static member, other forms are ok for pointer to static member. If
static and non-static members have the same name, we only discover the
error if overload resolution finds a non-static member.

To fix this I've use TREE_LANG_FLAG_0 in a new macro PTRMEM_OK_P. Which
is manipulated for OFFSET_REFs and ADDR_EXPRs, to indicate whether the
correct form has been encountered. Then in instantiate_type, I
have to pass this information down to resolve_address_of_overloaded_function
in order to determine whether a diagnostic should be issued or not.

Several tests needed tweaking as they now show candidate functions for
violations of this rule. Plus there are some exceptions to this to allow
microsoft compatibility when -fms-extensions is given. You'll see
two new testcases, one dealing with simple overload resolution and the
other dealing with template instantation where the difference in forms
can disambiguate type deduction.

built & tested on i686-pc-linux-gnu, approved by Mark

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
2000-08-15  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (PTRMEM_OK_P): New macro.
	(itf_ptrmem_ok): New enumeration value.
	* class.c (resolve_address_of_overloaded_function): Add PTRMEM
	argument. Diagnose implicit pointer to member.
	(instantiate_type): Don't diagnose implicit pointer to member
	here. Pass itf_ptrmem_ok if ok. Adjust calls to
	resolve_address_of_overloaded_function.
	* init.c (build_offset_ref): Set PTRMEM_OK_P.
	(resolve_offset_ref): Don't diagnose implicit pointer to member here.
	* semantics.c (finish_parenthesized_expr): Clear OFFSET_REFs here.
	* typeck.c (build_x_unary_op): Calculate PTRMEM_OK_P.
	(build_unary_op): Deal with single non-static member in
	microsoft-land.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.330
diff -c -3 -p -r1.330 class.c
*** class.c	2000/08/17 13:26:14	1.330
--- class.c	2000/08/17 14:11:16
*************** static int method_name_cmp PARAMS ((cons
*** 132,138 ****
  static tree add_implicitly_declared_members PARAMS ((tree, int, int, int));
  static tree fixed_type_or_null PARAMS ((tree, int *));
  static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
! 							  int, tree));
  static void build_vtable_entry_ref PARAMS ((tree, tree, tree));
  static tree build_vtbl_initializer PARAMS ((tree, tree, tree, tree, int *));
  static int count_fields PARAMS ((tree));
--- 132,138 ----
  static tree add_implicitly_declared_members PARAMS ((tree, int, int, int));
  static tree fixed_type_or_null PARAMS ((tree, int *));
  static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
! 							  int, int, tree));
  static void build_vtable_entry_ref PARAMS ((tree, tree, tree));
  static tree build_vtbl_initializer PARAMS ((tree, tree, tree, tree, int *));
  static int count_fields PARAMS ((tree));
*************** pop_lang_context ()
*** 5725,5743 ****
  /* Given an OVERLOAD and a TARGET_TYPE, return the function that
     matches the TARGET_TYPE.  If there is no satisfactory match, return
     error_mark_node, and issue an error message if COMPLAIN is
!    non-zero.  If TEMPLATE_ONLY, the name of the overloaded function
     was a template-id, and EXPLICIT_TARGS are the explicitly provided
     template arguments.  */
  
  static tree
  resolve_address_of_overloaded_function (target_type, 
  					overload,
! 					complain, 
  					template_only,
  					explicit_targs)
       tree target_type;
       tree overload;
       int complain;
       int template_only;
       tree explicit_targs;
  {
--- 5725,5746 ----
  /* Given an OVERLOAD and a TARGET_TYPE, return the function that
     matches the TARGET_TYPE.  If there is no satisfactory match, return
     error_mark_node, and issue an error message if COMPLAIN is
!    non-zero.  Permit pointers to member function if PTRMEM is non-zero.
!    If TEMPLATE_ONLY, the name of the overloaded function
     was a template-id, and EXPLICIT_TARGS are the explicitly provided
     template arguments.  */
  
  static tree
  resolve_address_of_overloaded_function (target_type, 
  					overload,
! 					complain,
! 	                                ptrmem,
  					template_only,
  					explicit_targs)
       tree target_type;
       tree overload;
       int complain;
+      int ptrmem;
       int template_only;
       tree explicit_targs;
  {
*************** resolve_address_of_overloaded_function (
*** 5960,5965 ****
--- 5963,5976 ----
    /* Good, exactly one match.  Now, convert it to the correct type.  */
    fn = TREE_PURPOSE (matches);
  
+   if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+       && !ptrmem && !flag_ms_extensions)
+     {
+       if (!complain)
+         return error_mark_node;
+ 
+       cp_pedwarn ("assuming pointer to member `%D'", fn);
+     }
    mark_used (fn);
  
    if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
*************** instantiate_type (lhstype, rhs, flags)
*** 5993,6000 ****
    int complain = (flags & itf_complain);
    int strict = (flags & itf_no_attributes)
                 ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
!   tree r;
    
    if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
      {
        if (complain)
--- 6004,6013 ----
    int complain = (flags & itf_complain);
    int strict = (flags & itf_no_attributes)
                 ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
!   int allow_ptrmem = flags & itf_ptrmem_ok;
    
+   flags &= ~itf_ptrmem_ok;
+   
    if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
      {
        if (complain)
*************** instantiate_type (lhstype, rhs, flags)
*** 6053,6088 ****
        return instantiate_type (lhstype, rhs, flags);
  
      case COMPONENT_REF:
!       {
! 	r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
  
-       comp:
- 	if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
- 	    && complain && !flag_ms_extensions)
- 	  {
- 	    /* Note: we check this after the recursive call to avoid
- 	       complaining about cases where overload resolution fails.  */
- 
- 	    tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
- 	    tree fn = PTRMEM_CST_MEMBER (r);
- 
- 	    my_friendly_assert (TREE_CODE (r) == PTRMEM_CST, 990811);
- 
- 	    cp_pedwarn
- 	      ("object-dependent reference to `%E' can only be used in a call",
- 	       DECL_NAME (fn));
- 	    cp_pedwarn
- 	      ("  to form a pointer to member function, say `&%T::%E'",
- 	       t, DECL_NAME (fn));
- 	  }
- 
- 	return r;
-       }
- 
      case OFFSET_REF:
        rhs = TREE_OPERAND (rhs, 1);
        if (BASELINK_P (rhs))
! 	return instantiate_type (lhstype, TREE_VALUE (rhs), flags);
  
        /* This can happen if we are forming a pointer-to-member for a
  	 member template.  */
--- 6066,6078 ----
        return instantiate_type (lhstype, rhs, flags);
  
      case COMPONENT_REF:
!       return instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
  
      case OFFSET_REF:
        rhs = TREE_OPERAND (rhs, 1);
        if (BASELINK_P (rhs))
! 	return instantiate_type (lhstype, TREE_VALUE (rhs),
! 	                         flags | allow_ptrmem);
  
        /* This can happen if we are forming a pointer-to-member for a
  	 member template.  */
*************** instantiate_type (lhstype, rhs, flags)
*** 6095,6112 ****
  	tree fns = TREE_OPERAND (rhs, 0);
  	tree args = TREE_OPERAND (rhs, 1);
  
! 	r =
  	  resolve_address_of_overloaded_function (lhstype,
  						  fns,
  						  complain,
  						  /*template_only=*/1,
  						  args);
- 	if (TREE_CODE (fns) == COMPONENT_REF)
- 	  {
- 	    rhs = fns;
- 	    goto comp;
- 	  }
- 	return r;
        }
  
      case OVERLOAD:
--- 6085,6097 ----
  	tree fns = TREE_OPERAND (rhs, 0);
  	tree args = TREE_OPERAND (rhs, 1);
  
! 	return
  	  resolve_address_of_overloaded_function (lhstype,
  						  fns,
  						  complain,
+ 	                                          allow_ptrmem,
  						  /*template_only=*/1,
  						  args);
        }
  
      case OVERLOAD:
*************** instantiate_type (lhstype, rhs, flags)
*** 6114,6119 ****
--- 6099,6105 ----
  	resolve_address_of_overloaded_function (lhstype, 
  						rhs,
  						complain,
+ 	                                        allow_ptrmem,
  						/*template_only=*/0,
  						/*explicit_targs=*/NULL_TREE);
  
*************** instantiate_type (lhstype, rhs, flags)
*** 6225,6232 ****
        return rhs;
        
      case ADDR_EXPR:
        return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
! 
      case ENTRY_VALUE_EXPR:
        my_friendly_abort (184);
        return error_mark_node;
--- 6211,6222 ----
        return rhs;
        
      case ADDR_EXPR:
+     {
+       if (PTRMEM_OK_P (rhs))
+         flags |= itf_ptrmem_ok;
+       
        return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
!     }
      case ENTRY_VALUE_EXPR:
        my_friendly_abort (184);
        return error_mark_node;
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.512
diff -c -3 -p -r1.512 cp-tree.h
*** cp-tree.h	2000/08/17 13:10:50	1.512
--- cp-tree.h	2000/08/17 14:11:18
*************** Boston, MA 02111-1307, USA.  */
*** 41,46 ****
--- 41,47 ----
        AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
        CTOR_BEGIN_P (in CTOR_STMT)
        BV_USE_VCALL_INDEX_P (in the BINFO_VIRTUALS TREE_LIST)
+       PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
     1: IDENTIFIER_VIRTUAL_P.
        TI_PENDING_TEMPLATE_FLAG.
        TEMPLATE_PARMS_FOR_INLINE.
*************** extern int flag_new_for_scope;
*** 2666,2671 ****
--- 2667,2676 ----
  #define TYPE_PTRMEMFUNC_FLAG(NODE) \
    (TYPE_LANG_SPECIFIC(NODE)->ptrmemfunc_flag)
  
+ /* Indicates when overload resolution may resolve to a pointer to
+    member function. [expr.unary.op]/3 */
+ #define PTRMEM_OK_P(NODE) TREE_LANG_FLAG_0 (NODE)
+ 
  /* A pointer-to-function member type looks like:
  
     struct {
*************** typedef enum special_function_kind {
*** 3208,3214 ****
  typedef enum instantiate_type_flags {
    itf_none = 0,               /* nothing special */
    itf_complain = 1 << 0,      /* complain about errors */
!   itf_no_attributes = 1 << 1  /* ignore attributes on comparisons */
  } instantiate_type_flags;
  
  /* Non-zero means that if a label exists, and no other identifier
--- 3213,3220 ----
  typedef enum instantiate_type_flags {
    itf_none = 0,               /* nothing special */
    itf_complain = 1 << 0,      /* complain about errors */
!   itf_no_attributes = 1 << 1, /* ignore attributes on comparisons */
!   itf_ptrmem_ok = 1 << 2,     /* pointers to member ok (internal use) */
  } instantiate_type_flags;
  
  /* Non-zero means that if a label exists, and no other identifier
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.212
diff -c -3 -p -r1.212 init.c
*** init.c	2000/08/10 12:32:40	1.212
--- init.c	2000/08/17 14:11:19
*************** build_offset_ref (type, name)
*** 1710,1722 ****
  	       expects to encounter OVERLOADs, not raw functions.  */
  	    t = ovl_cons (t, NULL_TREE);
  
! 	  return build (OFFSET_REF, 
! 			unknown_type_node,
! 			decl,
! 			build (TEMPLATE_ID_EXPR, 
! 			       TREE_TYPE (t),
! 			       t,
! 			       TREE_OPERAND (orig_name, 1)));
  	}
  
        if (!really_overloaded_fn (t))
--- 1710,1722 ----
  	       expects to encounter OVERLOADs, not raw functions.  */
  	    t = ovl_cons (t, NULL_TREE);
  
!           t = build (TEMPLATE_ID_EXPR, TREE_TYPE (t), t,
! 	             TREE_OPERAND (orig_name, 1));
! 	  t = build (OFFSET_REF, unknown_type_node, decl, t);
!           
!           PTRMEM_OK_P (t) = 1;
!           	  
! 	  return t;
  	}
  
        if (!really_overloaded_fn (t))
*************** build_offset_ref (type, name)
*** 1730,1740 ****
  	  mark_used (t);
  	  if (DECL_STATIC_FUNCTION_P (t))
  	    return t;
! 	  return build (OFFSET_REF, TREE_TYPE (t), decl, t);
  	}
  
        TREE_TYPE (fnfields) = unknown_type_node;
!       return build (OFFSET_REF, unknown_type_node, decl, fnfields);
      }
  
    t = member;
--- 1730,1745 ----
  	  mark_used (t);
  	  if (DECL_STATIC_FUNCTION_P (t))
  	    return t;
! 	  t = build (OFFSET_REF, TREE_TYPE (t), decl, t);
! 	  PTRMEM_OK_P (t) = 1;
! 	  return t;
  	}
  
        TREE_TYPE (fnfields) = unknown_type_node;
!       
!       t = build (OFFSET_REF, unknown_type_node, decl, fnfields);
!       PTRMEM_OK_P (t) = 1;
!       return t;
      }
  
    t = member;
*************** build_offset_ref (type, name)
*** 1772,1778 ****
    /* In member functions, the form `type::name' is no longer
       equivalent to `this->type::name', at least not until
       resolve_offset_ref.  */
!   return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
  }
  
  /* If a OFFSET_REF made it through to here, then it did
--- 1777,1785 ----
    /* In member functions, the form `type::name' is no longer
       equivalent to `this->type::name', at least not until
       resolve_offset_ref.  */
!   t = build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
!   PTRMEM_OK_P (t) = 1;
!   return t;
  }
  
  /* If a OFFSET_REF made it through to here, then it did
*************** resolve_offset_ref (exp)
*** 1806,1821 ****
      }
  
    if (BASELINK_P (member))
!     {
!       if (! flag_ms_extensions)
! 	cp_pedwarn ("assuming & on overloaded member function");
!       return build_unary_op (ADDR_EXPR, exp, 0);
!     }
! 
    if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
      {
!       if (! flag_ms_extensions)
! 	cp_pedwarn ("assuming & on `%E'", member);
        return build_unary_op (ADDR_EXPR, exp, 0);
      }
  
--- 1813,1827 ----
      }
  
    if (BASELINK_P (member))
!     return build_unary_op (ADDR_EXPR, exp, 0);
!   
    if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
      {
!       if (!flag_ms_extensions)
!         /* A single non-static member, make sure we don't allow a
!            pointer-to-member.  */
!         exp = ovl_cons (member, NULL_TREE);
!       
        return build_unary_op (ADDR_EXPR, exp, 0);
      }
  
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.163
diff -c -3 -p -r1.163 semantics.c
*** semantics.c	2000/08/04 18:41:00	1.163
--- semantics.c	2000/08/17 14:11:20
*************** finish_parenthesized_expr (expr)
*** 1331,1336 ****
--- 1331,1340 ----
      /* This inhibits warnings in truthvalue_conversion.  */
      C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK); 
  
+   if (TREE_CODE (expr) == OFFSET_REF)
+     /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
+        enclosed in parentheses.  */
+     PTRMEM_OK_P (expr) = 0;
    return expr;
  }
  
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.303
diff -c -3 -p -r1.303 typeck.c
*** typeck.c	2000/08/17 13:10:50	1.303
--- typeck.c	2000/08/17 14:11:23
*************** build_x_unary_op (code, xarg)
*** 4260,4265 ****
--- 4260,4268 ----
       enum tree_code code;
       tree xarg;
  {
+   tree exp;
+   int ptrmem = 0;
+   
    if (processing_template_decl)
      return build_min_nt (code, xarg, NULL_TREE);
  
*************** build_x_unary_op (code, xarg)
*** 4280,4293 ****
        if (rval || code != ADDR_EXPR)
  	return rval;
      }
- 
    if (code == ADDR_EXPR)
      {
!       if (TREE_CODE (xarg) == TARGET_EXPR)
  	warning ("taking address of temporary");
      }
  
!   return build_unary_op (code, xarg, 0);
  }
  
  /* Just like truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
--- 4283,4308 ----
        if (rval || code != ADDR_EXPR)
  	return rval;
      }
    if (code == ADDR_EXPR)
      {
!       if (TREE_CODE (xarg) == OFFSET_REF)
!         {
!           ptrmem = PTRMEM_OK_P (xarg);
!           
!           if (!ptrmem && !flag_ms_extensions
!               && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
!             /* A single non-static member, make sure we don't allow a
!                pointer-to-member.  */
!             xarg = ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE);
!         }
!       else if (TREE_CODE (xarg) == TARGET_EXPR)
  	warning ("taking address of temporary");
      }
+   exp = build_unary_op (code, xarg, 0);
+   if (TREE_CODE (exp) == ADDR_EXPR)
+     PTRMEM_OK_P (exp) = ptrmem;
  
!   return exp;
  }
  
  /* Just like truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
*************** build_unary_op (code, xarg, noconvert)
*** 4635,4669 ****
  	  return build1 (ADDR_EXPR, unknown_type_node, arg);
  	}
  
!       if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
! 	  && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
! 	{
  	  /* They're trying to take the address of a unique non-static
! 	     member function.  This is ill-formed, but let's try to DTRT.
! 	     Note: We only handle unique functions here because we don't
! 	     want to complain if there's a static overload; non-unique
! 	     cases will be handled by instantiate_type.  But we need to
! 	     handle this case here to allow casts on the resulting PMF.  */
  
  	  tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
  	  tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
- 
- 	  if (! flag_ms_extensions)
- 	    {
- 	      if (current_class_type
- 		  && TREE_OPERAND (arg, 0) == current_class_ref)
- 		/* An expression like &memfn.  */
- 		cp_pedwarn ("ISO C++ forbids taking the address of a non-static member function to form a pointer to member function.  Say `&%T::%D'", base, name);
- 	      else
- 		cp_pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function", base, name);
- 	    }
- 
  	  arg = build_offset_ref (base, name);
! 	}
! 
        if (type_unknown_p (arg))
  	return build1 (ADDR_EXPR, unknown_type_node, arg);
! 
        /* Handle complex lvalues (when permitted)
  	 by reduction to simpler cases.  */
        val = unary_complex_lvalue (code, arg);
--- 4650,4670 ----
  	  return build1 (ADDR_EXPR, unknown_type_node, arg);
  	}
  
!       if (TREE_CODE (arg) == COMPONENT_REF && flag_ms_extensions
!           && type_unknown_p (arg)
!           && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
!         {
  	  /* They're trying to take the address of a unique non-static
! 	     member function.  This is ill-formed, except in microsoft-land.  */
  
  	  tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
  	  tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
  	  arg = build_offset_ref (base, name);
!         }
!         
        if (type_unknown_p (arg))
  	return build1 (ADDR_EXPR, unknown_type_node, arg);
! 	
        /* Handle complex lvalues (when permitted)
  	 by reduction to simpler cases.  */
        val = unary_complex_lvalue (code, arg);
2000-08-15  Nathan Sidwell  <nathan@codesourcery.com>

	* g++.old-deja/g++.benjamin/13478.C: Mark candidate.
	* g++.old-deja/g++.mike/net36.C: Mark candidate.
	* g++.old-deja/g++.robertl/eb131.C: Mark candidate.
	* g++.old-deja/g++.oliva/overload1.C: Remove XFAIL.
	* g++.old-deja/g++.other/ptrmem7.C: New test.
	* g++.old-deja/g++.pt/ptrmem10.C: New test.
	
Index: testsuite/g++.old-deja/g++.benjamin/13478.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.benjamin/13478.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 13478.C
*** 13478.C	1998/12/16 21:21:38	1.2
--- 13478.C	2000/08/18 09:29:18
*************** protected:
*** 19,25 ****
    static const hand_table table_1[];
    static const AData 	  table_2;
  private:
!   void foo (void);
  };
  
  const hand_table Agent::table_1[] = 
--- 19,25 ----
    static const hand_table table_1[];
    static const AData 	  table_2;
  private:
!   void foo (void);                  // ERROR - candidate
  };
  
  const hand_table Agent::table_1[] = 
Index: testsuite/g++.old-deja/g++.mike/net36.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.mike/net36.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 net36.C
*** net36.C	1999/05/07 09:54:10	1.3
--- net36.C	2000/08/18 09:29:19
*************** typedef void (A::*handler) (X*);
*** 11,17 ****
  
  class B {
  public:
!   void setHandler(handler);
  };
  
  void f(B* b) {
--- 11,17 ----
  
  class B {
  public:
!   void setHandler(handler); // ERROR - candidate
  };
  
  void f(B* b) {
Index: testsuite/g++.old-deja/g++.oliva/overload1.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.oliva/overload1.C,v
retrieving revision 1.1
diff -c -3 -p -r1.1 overload1.C
*** overload1.C	1999/09/18 18:06:20	1.1
--- overload1.C	2000/08/18 09:29:19
*************** struct foo {
*** 12,18 ****
  
  /* gcc emits a hard error without -pedantic, and a warning with
     -pedantic, even in bad1.  */
! int (*ok1)() = foo::bar; // gets bogus error - XFAIL *-*-*
  void (foo::*bad1)(int) = foo::bar; // ERROR - missing &
  
  int (*ok2)() = &foo::bar; // ok
--- 12,18 ----
  
  /* gcc emits a hard error without -pedantic, and a warning with
     -pedantic, even in bad1.  */
! int (*ok1)() = foo::bar;
  void (foo::*bad1)(int) = foo::bar; // ERROR - missing &
  
  int (*ok2)() = &foo::bar; // ok
Index: testsuite/g++.old-deja/g++.other/ptrmem7.C
===================================================================
RCS file: ptrmem7.C
diff -N ptrmem7.C
*** /dev/null	Tue May  5 13:32:27 1998
--- ptrmem7.C	Fri Aug 18 02:29:19 2000
***************
*** 0 ****
--- 1,46 ----
+ // Build don't link:
+ // 
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 14 Aug 2000 <nathan@codesourcery.com>
+ 
+ // A pointer to member can only be formed by `&T::m', however, other forms
+ // are ok for pointer to static member. Thus the error can only be determined
+ // after overload resolution.
+ 
+ struct A
+ {
+   static int ns (short);
+   static int ns (float);
+   int ns (int);
+   int ns (double);
+   int single (int);
+   static int sole (short);
+   void foo ();
+ };
+ void A::foo ()
+ {
+   int (A::*ptr1) (int) = &A::ns;
+   int (A::*ptr2) (int) = A::ns;           // ERROR - not ptr mem
+   int (A::*ptr3) (int) = &ns;             // ERROR - not ptr mem
+   int (A::*ptr4) (int) = ns;              // ERROR - not ptr mem
+ 
+   int (*ptr5) (short) = &A::ns;
+   int (*ptr6) (short) = A::ns;
+   int (*ptr7) (short) = &ns;
+   int (*ptr8) (short) = ns;
+ 
+   int (A::*ptr11) (int) = &A::single;
+   int (A::*ptr12) (int) = A::single;      // ERROR - not ptr mem
+   int (A::*ptr13) (int) = &single;        // ERROR - not ptr mem
+   int (A::*ptr14) (int) = single;         // ERROR - not ptr mem
+ 
+   int (A::*ptr20) (int) = &(A::ns);       // ERROR - not ptr mem
+   int (A::*ptr21) (int) = &(A::single);   // ERROR - not ptr mem
+ 
+   int (*ptr31) (short) = &A::sole;
+   int (*ptr32) (short) = A::sole;
+   int (*ptr33) (short) = &sole;
+   int (*ptr34) (short) = sole;
+   int (*ptr41) (short) = &(A::sole);
+   int (*ptr43) (short) = &(sole);
+ }
Index: testsuite/g++.old-deja/g++.pt/ptrmem10.C
===================================================================
RCS file: ptrmem10.C
diff -N ptrmem10.C
*** /dev/null	Tue May  5 13:32:27 1998
--- ptrmem10.C	Fri Aug 18 02:29:20 2000
***************
*** 0 ****
--- 1,29 ----
+ // Build don't link:
+ // 
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 14 Aug 2000 <nathan@codesourcery.com>
+ 
+ // A pointer to member can only be formed by `&T::m', however, other forms
+ // are ok for pointer to static member. Thus the error can only be determined
+ // after overload resolution. In template deduction, this can disambiguate
+ // otherwise ambiguous cases.
+ 
+ struct A
+ {
+   static int f (int);
+   int f (short);
+   void baz ();
+ };
+ 
+ template <typename T> void foo (int (*)(T));      // ERROR - candidate
+ template <typename T> void foo (int (A::*)(T));   // ERROR - candidate
+ 
+ 
+ void A::baz ()
+ {
+   foo (&A::f);  // ERROR - ambiguous
+   foo (A::f);
+   foo (&(A::f));
+   foo (f);
+   foo (&f);
+ }
Index: testsuite/g++.old-deja/g++.robertl/eb131.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.robertl/eb131.C,v
retrieving revision 1.9
diff -c -3 -p -r1.9 eb131.C
*** eb131.C	1999/05/24 04:24:30	1.9
--- eb131.C	2000/08/18 09:29:20
*************** struct a {
*** 10,16 ****
  	void bar( double );
  	void bar( float );
  
!   void foo( void (a::*member)(float) );
  };
  
  a::a()
--- 10,16 ----
  	void bar( double );
  	void bar( float );
  
!   void foo( void (a::*member)(float) );   // ERROR - candidate
  };
  
  a::a()

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