typeck.c (composite_pointer_type): Add comment about DR 195
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 20 Oct 2004 14:30:52 +0000 (14:30 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 20 Oct 2004 14:30:52 +0000 (14:30 +0000)
cp:
* typeck.c (composite_pointer_type): Add comment about DR 195
(build_reinterpret_cast_1): Add for_reinterpret_cast_p parameter.
Allow function pointer conversions that DR195 suggests.
(build_reinterpret_cast, build_c_cast): Update
build_reinterpret_cast_1 calls.
testsuite:
* g++.dg/conversion/dr195.C: New.
* g++.old-deja/g++.mike/p10148.C: Remove ill-formed cast.

From-SVN: r89334

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/dr195.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.mike/p10148.C

index 088dac2303242ea22003c8eac26e981994be6928..6dc5345e2822584050d4df8533a2dabc99371e9a 100644 (file)
@@ -1,3 +1,11 @@
+2004-10-20  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * typeck.c (composite_pointer_type): Add comment about DR 195
+       (build_reinterpret_cast_1): Add for_reinterpret_cast_p parameter.
+       Allow function pointer conversions that DR195 suggests.
+       (build_reinterpret_cast, build_c_cast): Update
+       build_reinterpret_cast_1 calls. 
+
 2004-10-20  Kazu Hirata  <kazu@cs.umass.edu>
 
        * call.c, typeck.c: Fix comment typos.
index 763e4084b7ee374f05e198731d16066473365704..1c76944606cf264867b5ac28b147f97ad1a74b7f 100644 (file)
@@ -507,6 +507,8 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
       tree result_type;
 
       if (pedantic && TYPE_PTRFN_P (t2))
+       /* Although DR195 suggests allowing this when no precision is
+          lost, that is only allowed in a reinterpret_cast.  */
        pedwarn ("ISO C++ forbids %s between pointer of type %<void *%> "
                  "and pointer-to-function", location);
       result_type 
@@ -4803,7 +4805,7 @@ convert_member_func_to_ptr (tree type, tree expr)
 
 static tree
 build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
-                         bool *valid_p)
+                         bool for_reinterpret_ref_p, bool *valid_p)
 {
   tree intype;
 
@@ -4843,7 +4845,7 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
       expr = build_unary_op (ADDR_EXPR, expr, 0);
       if (expr != error_mark_node)
        expr = build_reinterpret_cast_1
-         (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
+         (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p, true,
           valid_p);
       if (expr != error_mark_node)
        expr = build_indirect_ref (expr, 0);
@@ -4922,7 +4924,24 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
           || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
     {
       if (pedantic || !c_cast_p)
-       pedwarn ("ISO C++ forbids casting between pointer-to-function and pointer-to-object");
+       {
+         /* DR 195 suggests allowing such casts if they do not lose
+            precision.  We allow conversion to pointer-to-void, if it
+            does not lose precision, and we allow conversion from
+            pointer-to-void regardless, so that one may convert
+            back again without warning.  Such conversions are not
+            permitted when we are recursively called to deal with
+            reinterpretting reference casts. */
+         if (!for_reinterpret_ref_p && VOID_TYPE_P (TREE_TYPE (type)))
+           {
+             if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
+               warning ("conversion from %qT to %qT loses precision",
+                        intype, type);
+           }
+         else if (for_reinterpret_ref_p || !VOID_TYPE_P (TREE_TYPE (intype)))
+           pedwarn ("ISO C++ forbids casting between pointer-to-function and pointer-to-object");
+       }
+      
       expr = decl_constant_value (expr);
       return fold_if_not_in_template (build_nop (type, expr));
     }
@@ -4955,6 +4974,7 @@ build_reinterpret_cast (tree type, tree expr)
     }
 
   return build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
+                                  /*for_reinterpret_ref=*/false,
                                   /*valid_p=*/NULL);
 }
 
@@ -5157,6 +5177,7 @@ build_c_cast (tree type, tree expr)
   /* Or a reinterpret_cast.  */
   if (!valid_p)
     result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
+                                      /*for_reinterpret_ref_p=*/false,
                                       &valid_p);
   /* The static_cast or reinterpret_cast may be followed by a
      const_cast.  */
index 1a7ccc05cbe344ff49e77de70bd8ad6355dc5e6d..04c73cd9989c5459858f15510e9671cd11e2233f 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-20  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/conversion/dr195.C: New.
+       * g++.old-deja/g++.mike/p10148.C: Remove ill-formed cast.
+
 2004-10-20  Ben Elliston  <bje@au.ibm.com>
            Devang Patel  <dpatel@apple.com>
 
diff --git a/gcc/testsuite/g++.dg/conversion/dr195.C b/gcc/testsuite/g++.dg/conversion/dr195.C
new file mode 100644 (file)
index 0000000..e6cf18e
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 20 Oct 2004 <nathan@codesourcery.com>
+
+// DR 195 allows conversions between function and object pointers
+// under some circumstances.
+
+typedef void (*PF)(void);
+typedef void *PV;
+typedef int *PO;
+
+
+void foo ()
+{
+  PF pf;
+  PV pv;
+  PO po;
+
+  pf = reinterpret_cast <PF>(pv);
+  pv = reinterpret_cast <PV>(pf);
+  pf = reinterpret_cast <PF>(po); // { dg-error "casting between" "" }
+  po = reinterpret_cast <PO>(pf); // { dg-error "casting between" "" }
+
+  pv = pf; // { dg-error "invalid conversion" "" }
+  pf = pv; // { dg-error "invalid conversion" "" }
+}
index 20fbf091894b3bef15816cb4b993e7aa091f910c..6661e6bf91ecd67c56db19d955d017ea530bf64e 100644 (file)
@@ -23,7 +23,7 @@ public:
 };
 
 void TCRCB::eat () {
- void *vp = (TIRD*)this->itc;
+ void *vp = (void *)((TIRD*)this)->itc;
  this->itc();
 }