public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: C++ pointer to member conversion fixes
@ 2007-08-20 19:45 Ollie Wild
  2007-08-20 20:34 ` Ollie Wild
  2007-08-31  5:13 ` Mark Mitchell
  0 siblings, 2 replies; 3+ messages in thread
From: Ollie Wild @ 2007-08-20 19:45 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1907 bytes --]

This patch implements a number of related fixes to C++ pointer to
member conversions.

According to the C++ standard, a pointer to member conversion maps
null pointers to members of the source type to null pointers to
members of the destination type.  GCC gets this wrong when multiple
inheritance forces a pointer to data member offset to be updated.
This patch fixes the problem by generating a conditional expression
inside convert_ptrmem.

It also refactors cp_convert_to_pointer by calling convert_ptrmem and
removing the unnecessary force parameter, and it refactors
get_delta_difference, by pushing some duplicate checks inside
get_delta_difference_1 (which has the side effect of adding a missing
check which resulted in an ICE).

To rectify a lack of pointer to member conversion tests, I've created
7 new tests which exercise various functionality.  Of these, only 5
pass without this patch.

Tested with a C/C++/Java bootstrap and testsuite on i686-pc-linux-gnu.

Ollie

:ADDPATCH c++:

2007-08-20  Ollie Wild  <aaw@google.com>

    * cvt.c (cp_convert_to_pointer): Remove force parameter. Call
    convert_ptrmem for pointer to member conversions.
    (convert_to_pointer_force): Update cp_convert_to_pointer call.
    (ocp_convert): Update cp_convert_to_pointer call.
    * typeck.c (convert_ptrmem): Add conditional for null pointers to
    members.
    (build_static_cast_1): Check can_convert for conversions in either
    direction.
    (get_delta_difference_1): New function.
    (get_delta_difference): Refactor to call get_delta_difference_1.

2007-08-20  Ollie Wild  <aaw@google.com>

    g++.dg/conversion/ptrmem2.C: New test.
    g++.dg/conversion/ptrmem3.C: New test.
    g++.dg/conversion/ptrmem4.C: New test.
    g++.dg/conversion/ptrmem5.C: New test.
    g++.dg/conversion/ptrmem6.C: New test.
    g++.dg/conversion/ptrmem7.C: New test.
    g++.dg/conversion/ptrmem8.C: New test.

[-- Attachment #2: convert_ptrmem.patch --]
[-- Type: text/x-patch, Size: 17481 bytes --]

diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 26165d9..ebfc7d0 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "decl.h"
 #include "target.h"
 
-static tree cp_convert_to_pointer (tree, tree, bool);
+static tree cp_convert_to_pointer (tree, tree);
 static tree convert_to_pointer_force (tree, tree);
 static tree build_type_conversion (tree, tree);
 static tree build_up_reference (tree, tree, int, tree);
@@ -71,12 +71,10 @@ static void warn_ref_binding (tree, tree, tree);
      else if dealing with method pointers, delegate
      else convert blindly
    else if converting class, pass off to build_type_conversion
-   else try C-style pointer conversion.  If FORCE is true then allow
-   conversions via virtual bases (these are permitted by reinterpret_cast,
-   but not static_cast).  */
+   else try C-style pointer conversion.  */
 
 static tree
-cp_convert_to_pointer (tree type, tree expr, bool force)
+cp_convert_to_pointer (tree type, tree expr)
 {
   tree intype = TREE_TYPE (expr);
   enum tree_code form;
@@ -174,61 +172,17 @@ cp_convert_to_pointer (tree type, tree expr, bool force)
 
       return build_nop (type, expr);
     }
-  else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
-    {
-      tree b1;
-      tree b2;
-      tree binfo;
-      enum tree_code code = PLUS_EXPR;
-      base_kind bk;
-
-      b1 = TYPE_PTRMEM_CLASS_TYPE (type);
-      b2 = TYPE_PTRMEM_CLASS_TYPE (intype);
-      binfo = lookup_base (b1, b2, ba_check, &bk);
-      if (!binfo)
-	{
-	  binfo = lookup_base (b2, b1, ba_check, &bk);
-	  code = MINUS_EXPR;
-	}
-      if (binfo == error_mark_node)
-	return error_mark_node;
-
-      if (bk == bk_via_virtual)
-	{
-	  if (force)
-	    warning (0, "pointer to member cast from %qT to %qT is via"
-		     " virtual base", intype, type);
-	  else
-	    {
-	      error ("pointer to member cast from %qT to %qT is"
-		     " via virtual base", intype, type);
-	      return error_mark_node;
-	    }
-	  /* This is a reinterpret cast, whose result is unspecified.
-	     We choose to do nothing.  */
-	  return build1 (NOP_EXPR, type, expr);
-	}
-
-      if (TREE_CODE (expr) == PTRMEM_CST)
-	expr = cplus_expand_constant (expr);
-
-      if (binfo && !integer_zerop (BINFO_OFFSET (binfo)))
-	expr = size_binop (code,
-			   build_nop (sizetype, expr),
-			   BINFO_OFFSET (binfo));
-      return build_nop (type, expr);
-    }
-  else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
-    return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
-			     /*c_cast_p=*/false);
+  else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
+	   || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
+    return convert_ptrmem (type, expr, /*allow_inverse_p=*/false,
+			   /*c_cast_p=*/false);
   else if (TYPE_PTRMEMFUNC_P (intype))
     {
       if (!warn_pmf2ptr)
 	{
 	  if (TREE_CODE (expr) == PTRMEM_CST)
 	    return cp_convert_to_pointer (type,
-					  PTRMEM_CST_MEMBER (expr),
-					  force);
+					  PTRMEM_CST_MEMBER (expr));
 	  else if (TREE_CODE (expr) == OFFSET_REF)
 	    {
 	      tree object = TREE_OPERAND (expr, 0);
@@ -333,7 +287,7 @@ convert_to_pointer_force (tree type, tree expr)
 	}
     }
 
-  return cp_convert_to_pointer (type, expr, true);
+  return cp_convert_to_pointer (type, expr);
 }
 
 /* We are passing something to a function which requires a reference.
@@ -720,7 +674,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
       return fold_if_not_in_template (convert_to_integer (type, e));
     }
   if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
-    return fold_if_not_in_template (cp_convert_to_pointer (type, e, false));
+    return fold_if_not_in_template (cp_convert_to_pointer (type, e));
   if (code == VECTOR_TYPE)
     {
       tree in_vtype = TREE_TYPE (e);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index f019608..47f925a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4866,9 +4866,19 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
 				    allow_inverse_p,
 				    c_cast_p);
       if (!integer_zerop (delta))
-	expr = cp_build_binary_op (PLUS_EXPR,
-				   build_nop (ptrdiff_type_node, expr),
-				   delta);
+	{
+	  tree cond, op1, op2;
+
+	  cond = cp_build_binary_op (EQ_EXPR,
+				     expr,
+				     build_int_cst (TREE_TYPE (expr), -1));
+	  op1 = build_nop (ptrdiff_type_node, expr);
+	  op2 = cp_build_binary_op (PLUS_EXPR, op1, delta);
+
+	  expr = fold_build3 (COND_EXPR, ptrdiff_type_node, cond, op1, op2);
+			 
+	}
+
       return build_nop (type, expr);
     }
   else
@@ -5099,7 +5109,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 	  t1 = intype;
 	  t2 = type;
 	}
-      if (can_convert (t1, t2))
+      if (can_convert (t1, t2) || can_convert (t2, t1))
 	{
 	  if (!c_cast_p)
 	    check_for_casting_away_constness (intype, type, diag_fn,
@@ -5965,7 +5975,43 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
   return build_modify_expr (lhs, modifycode, rhs);
 }
 
-\f
+/* Helper function for get_delta_difference which assumes FROM is a base
+   class of TO.  Returns a delta for the conversion of pointer-to-member
+   of FROM to pointer-to-member of TO.  If the conversion is invalid,
+   returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
+   If C_CAST_P is true, this conversion is taking place as part of a C-style
+   cast.  */
+
+static tree
+get_delta_difference_1 (tree from, tree to, bool c_cast_p)
+{
+  tree binfo;
+  base_kind kind;
+
+  binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind);
+  if (kind == bk_inaccessible || kind == bk_ambig)
+    {
+      error ("   in pointer to member function conversion");
+      return size_zero_node;
+    }
+  else if (binfo)
+    {
+      if (kind != bk_via_virtual)
+	return BINFO_OFFSET (binfo);
+      else
+	/* FROM is a virtual base class of TO.  Issue an error or warning
+	   depending on whether or not this is a reinterpret cast.  */
+	{
+	  error ("pointer to member conversion via virtual base %qT",
+		 BINFO_TYPE (binfo_from_vbase (binfo)));
+
+	  return size_zero_node;
+	}
+      }
+    else
+      return NULL_TREE;
+}
+
 /* Get difference in deltas for different pointer to member function
    types.  Returns an integer constant of type PTRDIFF_TYPE_NODE.  If
    the conversion is invalid, the constant is zero.  If
@@ -5983,56 +6029,36 @@ get_delta_difference (tree from, tree to,
 		      bool allow_inverse_p,
 		      bool c_cast_p)
 {
-  tree binfo;
-  base_kind kind;
   tree result;
 
-  /* Assume no conversion is required.  */
-  result = integer_zero_node;
-  binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind);
-  if (kind == bk_inaccessible || kind == bk_ambig)
-    error ("   in pointer to member function conversion");
-  else if (binfo)
-    {
-      if (kind != bk_via_virtual)
-	result = BINFO_OFFSET (binfo);
-      else
-	{
-	  tree virt_binfo = binfo_from_vbase (binfo);
-
-	  /* This is a reinterpret cast, we choose to do nothing.  */
-	  if (allow_inverse_p)
-	    warning (0, "pointer to member cast via virtual base %qT",
-		     BINFO_TYPE (virt_binfo));
-	  else
-	    error ("pointer to member conversion via virtual base %qT",
-		   BINFO_TYPE (virt_binfo));
-	}
-    }
-  else if (same_type_ignoring_top_level_qualifiers_p (from, to))
-    /* Pointer to member of incomplete class is permitted*/;
-  else if (!allow_inverse_p)
-    {
-      error_not_base_type (from, to);
-      error ("   in pointer to member conversion");
-    }
+  if (same_type_ignoring_top_level_qualifiers_p (from, to))
+    /* Pointer to member of incomplete class is permitted*/
+    result = size_zero_node;
   else
-    {
-      binfo = lookup_base (from, to, c_cast_p ? ba_unique : ba_check, &kind);
-      if (binfo)
-	{
-	  if (kind != bk_via_virtual)
-	    result = size_diffop (size_zero_node, BINFO_OFFSET (binfo));
-	  else
-	    {
-	      /* This is a reinterpret cast, we choose to do nothing.  */
-	      tree virt_binfo = binfo_from_vbase (binfo);
+    result = get_delta_difference_1 (from, to, c_cast_p);
 
-	      warning (0, "pointer to member cast via virtual base %qT",
-		       BINFO_TYPE (virt_binfo));
-	    }
-	}
-    }
+  if (!result)
+  {
+    if (!allow_inverse_p)
+      {
+	error_not_base_type (from, to);
+	error ("   in pointer to member conversion");
+	result = size_zero_node;
+      }
+    else
+      {
+	result = get_delta_difference_1 (to, from, c_cast_p);
+
+	if (result)
+	  result = size_diffop (size_zero_node, result);
+	else
+	  {
+	    error_not_base_type (from, to);
+	    error ("   in pointer to member conversion");
+	    result = size_zero_node;
+	  }
+      }
+  }
 
   return fold_if_not_in_template (convert_to_integer (ptrdiff_type_node,
 						      result));
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem2.C b/gcc/testsuite/g++.dg/conversion/ptrmem2.C
new file mode 100644
index 0000000..db39fc0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem2.C
@@ -0,0 +1,39 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Assorted pointer to data member static cast tests.
+
+struct A { int x; };
+struct B : A { int x; };
+struct P : A { int x; };
+struct V { int x; };
+struct D : B, virtual V, private P { int x; };
+
+// Valid static casts.
+int B::*p1 = static_cast<int B::*>(&D::x);
+int D::*p2 = static_cast<int D::*>(&B::x);
+
+// Virtual base class.
+int V::*p3 = static_cast<int V::*>(&D::x);  // { dg-error "" }
+int D::*p4 = static_cast<int D::*>(&V::x);  // { dg-error "" }
+
+// Inaccessible base class.
+int P::*p5 = static_cast<int P::*>(&D::x);  // { dg-error "" }
+int D::*p6 = static_cast<int D::*>(&P::x);  // { dg-error "" }
+
+// Ambiguous base class.
+int A::*p7 = static_cast<int A::*>(&D::x);  // { dg-error "" }
+int D::*p8 = static_cast<int D::*>(&A::x);  // { dg-error "" }
+
+// Valid conversions which increase cv-qualification.
+const int B::*p9 = static_cast<const int B::*>(&D::x);
+const int D::*p10 = static_cast<const int D::*>(&B::x);
+
+// Invalid conversions which decrease cv-qualification.
+int B::*p11 = static_cast<int B::*>(p10); // { dg-error "casts away constness" }
+int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "casts away constness" }
+
+// Attempts to change member type.
+float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "" }
+float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem3.C b/gcc/testsuite/g++.dg/conversion/ptrmem3.C
new file mode 100644
index 0000000..13005e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem3.C
@@ -0,0 +1,31 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Assorted pointer to member function static cast tests.
+
+struct A { int f (); };
+struct B : A { int f (); };
+struct P : A { int f (); };
+struct V { int f (); };
+struct D : B, virtual V, private P { int f (); };
+
+// Valid static casts.
+int (B::*p1)() = static_cast<int (B::*)()>(&D::f);
+int (D::*p2)() = static_cast<int (D::*)()>(&B::f);
+
+// Virtual base class.
+int (V::*p3)() = static_cast<int (V::*)()>(&D::f);  // { dg-error "" }
+int (D::*p4)() = static_cast<int (D::*)()>(&V::f);  // { dg-error "" }
+
+// Inaccessible base class.
+int (P::*p5)() = static_cast<int (P::*)()>(&D::f);  // { dg-error "" }
+int (D::*p6)() = static_cast<int (D::*)()>(&P::f);  // { dg-error "" }
+
+// Ambiguous base class.
+int (A::*p7)() = static_cast<int (A::*)()>(&D::f);  // { dg-error "" }
+int (D::*p8)() = static_cast<int (D::*)()>(&A::f);  // { dg-error "" }
+
+// Attempts to change member type.
+float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "" }
+float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem4.C b/gcc/testsuite/g++.dg/conversion/ptrmem4.C
new file mode 100644
index 0000000..fd260df
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem4.C
@@ -0,0 +1,43 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Assorted pointer to data member c-style cast tests.
+
+struct X {};
+struct A { int x; };
+struct B : A { int x; };
+struct P : A { int x; };
+struct V { int x; };
+struct D : B, virtual V, private P { int x; };
+
+// Accessible, non-virtual, non-ambiguous base clas.
+int B::*p1 = (int B::*)&D::x;
+int D::*p2 = (int D::*)&B::x;
+
+// Virtual base class.
+int V::*p3 = (int V::*)&D::x;  // { dg-error "" }
+int D::*p4 = (int D::*)&V::x;  // { dg-error "" }
+
+// Inaccessible base class.
+int P::*p5 = (int P::*)&D::x;
+int D::*p6 = (int D::*)&P::x;
+
+// Ambiguous base class.
+int A::*p7 = (int A::*)&D::x;  // { dg-error "" }
+int D::*p8 = (int D::*)&A::x;  // { dg-error "" }
+
+// Valid conversions which increase cv-qualification.
+const int B::*p9 = (const int B::*)&D::x;
+const int D::*p10 = (const int D::*)&B::x;
+
+// Valid conversions which decrease cv-qualification.
+int B::*p11 = (int B::*)p10;
+int D::*p12 = (int D::*)p9;
+
+// Attempts to change member type allowed via reinterpret_cast.
+float B::*p13 = (float B::*)&D::x;
+float D::*p14 = (float D::*)&B::x;
+
+// Conversion via unrelated classes allwed via reinterpret_cast.
+int X::*p15 = (int X::*)&D::x;
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem5.C b/gcc/testsuite/g++.dg/conversion/ptrmem5.C
new file mode 100644
index 0000000..6f06bad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem5.C
@@ -0,0 +1,35 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Assorted pointer to member function c-style cast tests.
+
+struct X {};
+struct A { int f (); };
+struct B : A { int f (); };
+struct P : A { int f (); };
+struct V { int f (); };
+struct D : B, virtual V, private P { int f (); };
+
+// Accessible, non-virtual, non-ambiguous base clas.
+int (B::*p1)() = (int (B::*)())&D::f;
+int (D::*p2)() = (int (D::*)())&B::f;
+
+// Virtual base class.
+int (V::*p3)() = (int (V::*)())&D::f;  // { dg-error "" }
+int (D::*p4)() = (int (D::*)())&V::f;  // { dg-error "" }
+
+// Inaccessible base class.
+int (P::*p5)() = (int (P::*)())&D::f;
+int (D::*p6)() = (int (D::*)())&P::f;
+
+// Ambiguous base class.
+int (A::*p7)() = (int (A::*)())&D::f;  // { dg-error "" }
+int (D::*p8)() = (int (D::*)())&A::f;  // { dg-error "" }
+
+// Attempts to change member type allowed via reinterpret_cast.
+float (B::*p13)() = (float (B::*)())&D::f;
+float (D::*p14)() = (float (D::*)())&B::f;
+
+// Conversion via unrelated classes allwed via reinterpret_cast.
+int (X::*p15)() = (int (X::*)())&D::f;
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem6.C b/gcc/testsuite/g++.dg/conversion/ptrmem6.C
new file mode 100644
index 0000000..a3c0c96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem6.C
@@ -0,0 +1,35 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Assorted pointer to data member implicit cast tests.
+
+struct A { int x; };
+struct B : A { int x; };
+struct P : A { int x; };
+struct V { int x; };
+struct D : B, virtual V, private P { int x; };
+
+// Valid.
+int D::*p1 = &B::x;
+
+// Derived class.
+int B::*p2 = &D::x; // { dg-error "" }
+
+// Virtual base class.
+int D::*p3 = &V::x; // { dg-error "" }
+
+// Inaccessible base class.
+int D::*p4 = &P::x; // { dg-error "" }
+
+// Ambiguous base class.
+int D::*p5 = &A::x;  // { dg-error "" }
+
+// Increases cv-qualification.
+const int D::*p6 = &B::x;
+
+// Decreases cv-qualification.
+int D::*p7 = static_cast<const int D::*>(&D::x); // { dg-error "" }
+
+// Different member type.
+float D::*p8 = &B::x;  // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem7.C b/gcc/testsuite/g++.dg/conversion/ptrmem7.C
new file mode 100644
index 0000000..ad75a52
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem7.C
@@ -0,0 +1,29 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Assorted pointer to member function implicit cast tests.
+
+struct A { int f (); };
+struct B : A { int f (); };
+struct P : A { int f (); };
+struct V { int f (); };
+struct D : B, virtual V, private P { int f (); };
+
+// Valid.
+int (D::*p1)() = &B::f;
+
+// Derived class.
+int (B::*p2)() = &D::f; // { dg-error "" }
+
+// Virtual base class.
+int (D::*p3)() = &V::f; // { dg-error "" }
+
+// Inaccessible base class.
+int (D::*p4)() = &P::f; // { dg-error "" }
+
+// Ambiguous base class.
+int (D::*p5)() = &A::f;  // { dg-error "" }
+
+// Different member type.
+float (D::*p6)() = &B::f;  // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem8.C b/gcc/testsuite/g++.dg/conversion/ptrmem8.C
new file mode 100644
index 0000000..95d902f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ptrmem8.C
@@ -0,0 +1,25 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do run }
+
+// Test for proper conversion of null pointers to data members.
+
+struct B1 {
+  int x;
+};
+
+struct B2 {
+  int x;
+};
+
+struct D : B1, B2 {
+  int x;
+};
+
+int main ()
+{
+  int D::*pd = 0;
+  int B2::*pb2 = 0;
+
+  return pd != pb2;
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: C++ pointer to member conversion fixes
  2007-08-20 19:45 PATCH: C++ pointer to member conversion fixes Ollie Wild
@ 2007-08-20 20:34 ` Ollie Wild
  2007-08-31  5:13 ` Mark Mitchell
  1 sibling, 0 replies; 3+ messages in thread
From: Ollie Wild @ 2007-08-20 20:34 UTC (permalink / raw)
  To: GCC Patches

On 8/20/07, Ollie Wild <aaw@google.com> wrote:
> To rectify a lack of pointer to member conversion tests, I've created
> 7 new tests which exercise various functionality.  Of these, only 5
> pass without this patch.

A slight correction.  That should read, "Of these, only 2 pass without
this patch."

Ollie

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: C++ pointer to member conversion fixes
  2007-08-20 19:45 PATCH: C++ pointer to member conversion fixes Ollie Wild
  2007-08-20 20:34 ` Ollie Wild
@ 2007-08-31  5:13 ` Mark Mitchell
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Mitchell @ 2007-08-31  5:13 UTC (permalink / raw)
  To: Ollie Wild; +Cc: GCC Patches

Ollie Wild wrote:

> :ADDPATCH c++:
> 
> 2007-08-20  Ollie Wild  <aaw@google.com>
> 
>     * cvt.c (cp_convert_to_pointer): Remove force parameter. Call
>     convert_ptrmem for pointer to member conversions.
>     (convert_to_pointer_force): Update cp_convert_to_pointer call.
>     (ocp_convert): Update cp_convert_to_pointer call.
>     * typeck.c (convert_ptrmem): Add conditional for null pointers to
>     members.
>     (build_static_cast_1): Check can_convert for conversions in either
>     direction.
>     (get_delta_difference_1): New function.
>     (get_delta_difference): Refactor to call get_delta_difference_1.
> 
> 2007-08-20  Ollie Wild  <aaw@google.com>
> 
>     g++.dg/conversion/ptrmem2.C: New test.
>     g++.dg/conversion/ptrmem3.C: New test.
>     g++.dg/conversion/ptrmem4.C: New test.
>     g++.dg/conversion/ptrmem5.C: New test.
>     g++.dg/conversion/ptrmem6.C: New test.
>     g++.dg/conversion/ptrmem7.C: New test.
>     g++.dg/conversion/ptrmem8.C: New test.

:REVIEWMAIL: OK

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-08-31  3:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-20 19:45 PATCH: C++ pointer to member conversion fixes Ollie Wild
2007-08-20 20:34 ` Ollie Wild
2007-08-31  5:13 ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).