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
This commit is contained in:
Nathan Sidwell 2004-10-20 14:30:52 +00:00 committed by Nathan Sidwell
parent d0edbeeca0
commit 23517e6b4e
5 changed files with 63 additions and 4 deletions

View 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.

View 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. */

View 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>

View File

@ -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" "" }
}

View File

@ -23,7 +23,7 @@ public:
};
void TCRCB::eat () {
void *vp = (TIRD*)this->itc;
void *vp = (void *)((TIRD*)this)->itc;
this->itc();
}