Commit e18724aa by Jason Merrill Committed by Jason Merrill

re PR c++/56104 (Wrong "dereferencing type-punned pointer" warning)

	PR c++/56104
	* typeck.c (get_member_function_from_ptrfunc): Optimize if the
	dynamic type has no virtual functions.

From-SVN: r195470
parent b7d7d917
2013-01-25 Jason Merrill <jason@redhat.com>
PR c++/56104
* typeck.c (get_member_function_from_ptrfunc): Optimize if the
dynamic type has no virtual functions.
2013-01-22 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55944
......
......@@ -3122,7 +3122,8 @@ build_array_ref (location_t loc, tree array, tree idx)
With the final ISO C++ rules, such an optimization is
incorrect: A pointer to a derived member can be static_cast
to pointer-to-base-member, as long as the dynamic object
later has the right member. */
later has the right member. So now we only do this optimization
when we know the dynamic type of the object. */
tree
get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
......@@ -3133,8 +3134,10 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
{
tree idx, delta, e1, e2, e3, vtbl, basetype;
tree idx, delta, e1, e2, e3, vtbl;
bool nonvirtual;
tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
tree instance_ptr = *instance_ptrptr;
tree instance_save_expr = 0;
......@@ -3157,6 +3160,12 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
}
}
/* True if we know that the dynamic type of the object doesn't have
virtual functions, so we can assume the PFN field is a pointer. */
nonvirtual = (COMPLETE_TYPE_P (basetype)
&& !TYPE_POLYMORPHIC_P (basetype)
&& resolves_to_fixed_type_p (instance_ptr, 0));
if (TREE_SIDE_EFFECTS (instance_ptr))
instance_ptr = instance_save_expr = save_expr (instance_ptr);
......@@ -3167,7 +3176,9 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
e3 = pfn_from_ptrmemfunc (function);
delta = delta_from_ptrmemfunc (function);
idx = build1 (NOP_EXPR, vtable_index_type, e3);
switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
if (nonvirtual)
e1 = integer_zero_node;
else switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
e1 = cp_build_binary_op (input_location,
......@@ -3204,7 +3215,6 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
a member of C, and no conversion is required. In fact,
lookup_base will fail in that case, because incomplete
classes do not have BINFOs. */
basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
if (!same_type_ignoring_top_level_qualifiers_p
(basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
{
......@@ -3221,6 +3231,10 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
/* Hand back the adjusted 'this' argument to our caller. */
*instance_ptrptr = instance_ptr;
if (nonvirtual)
/* Now just return the pointer. */
return e3;
/* Next extract the vtable pointer from the object. */
vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
instance_ptr);
......@@ -3228,11 +3242,6 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
if (vtbl == error_mark_node)
return error_mark_node;
/* If the object is not dynamic the access invokes undefined
behavior. As it is not executed in this case silence the
spurious warnings it may provoke. */
TREE_NO_WARNING (vtbl) = 1;
/* Finally, extract the function pointer from the vtable. */
e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
e2 = cp_build_indirect_ref (e2, RO_NULL, complain);
......
// PR c++/56104
// { dg-options "-Wall -O2" }
struct Foo
{
Foo();
Foo(const Foo&);
void call()
{}
};
template<class MEMSIG, MEMSIG MEMFUNC>
struct Wrap
{
inline static void call( Foo cc )
{
(cc.*MEMFUNC)(); // <- warning here
}
};
void bar()
{
Wrap<void (Foo::*)(), &Foo::call>::call( Foo() );
}
// { dg-do run }
// extern "C" printf(const char *, ...);
// extern "C" int printf(const char *, ...);
class X
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment