diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2004-10-20 14:30:52 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2004-10-20 14:30:52 +0000 |
commit | 23517e6b4ea01d0af35984f8473a235a29ff93c7 (patch) | |
tree | ba3327f2ab451820b06d2c428829a4bcd7de53f9 | |
parent | d0edbeeca0a741b5edbeaea909f27fe09478143e (diff) | |
download | gcc-23517e6b4ea01d0af35984f8473a235a29ff93c7.tar.gz |
typeck.c (composite_pointer_type): Add comment about DR 195
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
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/dr195.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/p10148.C | 2 |
5 files changed, 63 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 088dac23032..6dc5345e282 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 763e4084b7e..1c76944606c 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a7ccc05cbe..04c73cd9989 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 00000000000..e6cf18e4ae4 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/dr195.C @@ -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" "" } +} diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10148.C b/gcc/testsuite/g++.old-deja/g++.mike/p10148.C index 20fbf091894..6661e6bf91e 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p10148.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p10148.C @@ -23,7 +23,7 @@ public: }; void TCRCB::eat () { - void *vp = (TIRD*)this->itc; + void *vp = (void *)((TIRD*)this)->itc; this->itc(); } |