call.c (standard_conversion): Reject pointer to member conversions from ambiguous...
authorNathan Sidwell <nathan@codesourcery.com>
Fri, 1 Dec 2000 11:52:33 +0000 (11:52 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Fri, 1 Dec 2000 11:52:33 +0000 (11:52 +0000)
cp:
* call.c (standard_conversion): Reject pointer to member
conversions from ambiguous, inaccessible or virtual bases.
* typeck.c (build_static_cast): Don't check pointers to members
specially.
testsuite:
* g++.old-deja/g++.other/cast6.C: New test.

From-SVN: r37914

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/cast6.C [new file with mode: 0644]

index 8c3934fca20b724285185c6b9838b9c912110b48..8654377980d804a9ac0cc03f2409fbef39ec9bef 100644 (file)
@@ -1,3 +1,10 @@
+2000-12-01  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * call.c (standard_conversion): Reject pointer to member
+       conversions from ambiguous, inaccessible or virtual bases.
+       * typeck.c (build_static_cast): Don't check pointers to members
+       specially.
+
 2000-11-30  Nathan Sidwell  <nathan@codesourcery.com>
 
        * method.c (do_build_copy_constructor): Preserve cv
index ecd3d22347e90717d045e65a9cb8429e172e90e6..fd5f904638215c1214b8dcaf8f0f9d07555d34d9 100644 (file)
@@ -736,8 +736,9 @@ standard_conversion (to, from, expr)
        {
          tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
          tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
+         tree binfo = get_binfo (fbase, tbase, 1);
 
-         if (DERIVED_FROM_P (fbase, tbase)
+         if (binfo && !binfo_from_vbase (binfo)
              && (same_type_ignoring_top_level_qualifiers_p
                  (TREE_TYPE (TREE_TYPE (from)),
                   TREE_TYPE (TREE_TYPE (to)))))
@@ -783,11 +784,12 @@ standard_conversion (to, from, expr)
       tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
       tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
       tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
+      tree binfo = get_binfo (fbase, tbase, 1);
 
-      if (! DERIVED_FROM_P (fbase, tbase)
-         || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
-         || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
-                         TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
+      if (!binfo || binfo_from_vbase (binfo)
+         || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
+         || !compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
+                        TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
          || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))
        return 0;
 
index 39f8b54515ee1321337d427d5df8554e07625e91..6f99a5fb6770e51137b3bfd424d791d705081fbe 100644 (file)
@@ -5095,23 +5095,18 @@ build_static_cast (type, expr)
       ? can_convert_arg (type, intype, expr)
       : can_convert_arg (strip_all_pointer_quals (type),
                          strip_all_pointer_quals (intype), expr))
+    /* This is a standard conversion. */
     ok = 1;
   else if (TYPE_PTROB_P (type) && TYPE_PTROB_P (intype))
     {
+      /* They're pointers to objects. They must be aggregates that
+         are related non-virtually. */
+      
       tree binfo;
+      
       if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
          && (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
-         && ! TREE_VIA_VIRTUAL (binfo))
-       ok = 1;
-    }
-  else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
-    {
-      if (same_type_ignoring_top_level_qualifiers_p
-         (TREE_TYPE (TREE_TYPE (type)),
-          TREE_TYPE (TREE_TYPE (intype)))
-         && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)),
-                                TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0))
-         && ! TREE_VIA_VIRTUAL (binfo))
+         && !binfo_from_vbase (binfo))
        ok = 1;
     }
   else if (TREE_CODE (intype) != BOOLEAN_TYPE
index 3363678eb1058dd2eae3b1967f02bab532349b6d..aae082d791f1b90111a6d0f6cc4d51efc74dfc75 100644 (file)
@@ -1,3 +1,7 @@
+2000-12-01  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.other/cast6.C: New test.
+
 2000-11-30  Geoffrey Keating  <geoffk@redhat.com>
 
        * gcc.c-torture/execute/20001130-2.c: New testcase.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cast6.C b/gcc/testsuite/g++.old-deja/g++.other/cast6.C
new file mode 100644 (file)
index 0000000..23f63e7
--- /dev/null
@@ -0,0 +1,57 @@
+// Build don't link:
+
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 28 Nov 2000 <nathan@codesourcery.com>
+
+// We failed to reject static_cast and implicit conversions of pointers to
+// member that traversed a virtual base.
+
+struct bar
+{
+  int barm;
+    static void a();
+};
+struct filler1 {int fm;};
+struct filler2 {int fm;};
+struct filler3 {int fm;};
+struct filler4 {int fm;};
+
+struct baz : filler1, bar, filler2
+{
+  int bazm;
+};
+
+struct foo : filler3, virtual baz, filler4
+{
+    static void a();
+    void b() {};
+    int m;
+};
+
+typedef void (bar::*barfPtr)();
+typedef void (foo::*foofPtr)();
+typedef int bar::*barmPtr;
+typedef int foo::*foomPtr;
+
+struct X;
+typedef void (X::*xfPtr) ();
+typedef int X::*xmPtr;
+
+int main ()
+{
+  {
+    foofPtr fp = &foo::b;
+    barfPtr bp = static_cast <barfPtr> (fp);    // ERROR - invalid static_cast
+    foofPtr fp2 = static_cast <foofPtr> (bp);   // ERROR - invalid static_cast
+    foofPtr fp3 = bp;                           // ERROR - cannot convert
+    fp3 = (foofPtr)bp;                          // WARNING - via virtual base
+    
+    foomPtr fmp = &foo::m;
+    barmPtr bmp = static_cast <barmPtr> (fmp);  // ERROR - invalid static_cast
+    foomPtr fmp2 = static_cast <foomPtr> (bmp); // ERROR - invalid static_cast
+    foomPtr fmp3 = bmp;                         // ERROR - cannot convert
+    fmp3 = (foomPtr)bmp;                        // WARNING - via virtual base
+  }
+  
+  return 0;
+}