* C++ PATCH for c++/56104 (bogus warning with pointer to member function)
@ 2013-01-25 17:57 Jason Merrill
2013-01-31 16:15 ` C++ PATCH for c++/56162 (pmf1.C failure on arm) Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2013-01-25 17:57 UTC (permalink / raw)
To: gcc-patches List
[-- Attachment #1: Type: text/plain, Size: 394 bytes --]
We were getting type-punning warnings while building up code to
dereference a pointer to member function because the compiler can see
that the complete object doesn't have a vtable. In such cases, we can
also see that and avoid building up that code in the first place.
Tested x86_64-pc-linux-gnu, applying to trunk. I'm inclined not to
apply it to 4.7, since it's just a bogus warning.
[-- Attachment #2: 56104.patch --]
[-- Type: text/x-patch, Size: 4695 bytes --]
commit 337b414b3475c8e3d9a504046da549b2b2f69a27
Author: Jason Merrill <jason@redhat.com>
Date: Fri Jan 25 10:37:26 2013 -0500
PR c++/56104
* typeck.c (get_member_function_from_ptrfunc): Optimize if the
dynamic type has no virtual functions.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 093e7c1..bfac394 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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);
diff --git a/gcc/testsuite/g++.dg/warn/pmf2.C b/gcc/testsuite/g++.dg/warn/pmf2.C
new file mode 100644
index 0000000..be13819
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pmf2.C
@@ -0,0 +1,24 @@
+// 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() );
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C b/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C
index 15460eb..aa1ea3e 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C
@@ -1,5 +1,5 @@
// { dg-do run }
-// extern "C" printf(const char *, ...);
+// extern "C" int printf(const char *, ...);
class X
{
^ permalink raw reply [flat|nested] 2+ messages in thread
* C++ PATCH for c++/56162 (pmf1.C failure on arm)
2013-01-25 17:57 C++ PATCH for c++/56104 (bogus warning with pointer to member function) Jason Merrill
@ 2013-01-31 16:15 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2013-01-31 16:15 UTC (permalink / raw)
To: gcc-patches List
[-- Attachment #1: Type: text/plain, Size: 202 bytes --]
In my 56104 patch I failed to notice that in the ARM (vbit in delta)
case, we need to adjust the delta even if we know we're doing a
non-virtual call.
Tested x86_64-pc-linux-gnu, applying to trunk.
[-- Attachment #2: 56162.patch --]
[-- Type: text/x-patch, Size: 851 bytes --]
commit 6a52d34876377448990d550cb763171180f44444
Author: Jason Merrill <jason@redhat.com>
Date: Thu Jan 31 09:45:49 2013 -0500
PR c++/56162
PR c++/56104
* typeck.c (get_member_function_from_ptrfunc): Fix
ptrmemfunc_vbit_in_delta case.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index bfac394..688c266 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3176,9 +3176,7 @@ 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);
- if (nonvirtual)
- e1 = integer_zero_node;
- else switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
+ switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
e1 = cp_build_binary_op (input_location,
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-01-31 15:22 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-25 17:57 C++ PATCH for c++/56104 (bogus warning with pointer to member function) Jason Merrill
2013-01-31 16:15 ` C++ PATCH for c++/56162 (pmf1.C failure on arm) Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).