From 8bd206211ddadcfb501aeed34d137ffd5baee59a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 5 Aug 2008 18:22:00 -0400 Subject: [PATCH] re PR c++/37016 (member function pointer failure with optimization) PR c++/37016 * tree-ssa.c (useless_type_conversion_p_1): Call langhook if TYPE_STRUCTURAL_EQUALITY_P is true for both types. From-SVN: r138740 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/opt/pmf1.C | 76 +++++++++++++++++++++++++++++++++++++++++ gcc/tree-ssa.c | 10 ++++-- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pmf1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8bce42a..eb2467b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-08-04 Jason Merrill + + PR c++/37016 + * tree-ssa.c (useless_type_conversion_p_1): Call langhook + if TYPE_STRUCTURAL_EQUALITY_P is true for both types. + 2008-08-05 Richard Henderson * configure.ac (HAVE_GAS_CFI_DIRECTIVE): Check .cfi_personality. diff --git a/gcc/testsuite/g++.dg/opt/pmf1.C b/gcc/testsuite/g++.dg/opt/pmf1.C new file mode 100644 index 0000000..428e753 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pmf1.C @@ -0,0 +1,76 @@ +// PR c++/37016 +// { dg-do run } +// { dg-options "-O2 -Wall" } + +/* + Basic design concept is that WorldObject implements remote method call + functionality using the "curiously recurring template pattern" to enable + forwarding calls from the generic base class that implements the transport + layer to the derived class. + + The specific failure was in forwarding calls to items in a container. + This is emulated here by wrapping a single item. + + In the main program there are two forms of the call. In the last + (uncommented) form the member function pointer is for clarity + assigned to a variable (itemfunptr) before making the call. + With 4.3.0 and 4.3.1 this code compiles incorrectly with -O1 or greater + to produce this warning + + reproduce.cc: In function ‘int main()’: + reproduce.cc:26: warning: ‘itemfunptr.void (Container::*)(void +(Item::*)(int), int)::__pfn’ is used uninitialized in this function + reproduce.cc:47: note: ‘itemfunptr.void (Container::*)(void (Item::*)(int), +int)::__pfn’ was declared here + + and the resulting executable segvs. It works correctly with -O0. + + With 4.2.3 and earlier it works correctly with optimization. + + In the first (commented out) form of the call in the main program + we directly refer to desired member function. This compiles + and executes correctly with all tested versions. +*/ + +extern "C" int printf (const char *, ...); + +template +struct WorldObject { + template + void forward(memfunT memfun, arg1T arg1, arg2T arg2) { + Derived* obj = static_cast(this); + (obj->*memfun)(arg1, arg2); + } +}; + +struct Item { + void fred(int a) { + printf ("a=%d\n", a); + } +}; + +struct Container : public WorldObject { + Item item; + template + void itemfun(itemfunT itemfun, int a) { + (item.*itemfun)(a); + } +}; + +int main() { + typedef void (Item::*itemfun)(int); + + Container t; + + // This call compiles and executes correctly with all versions tested + //t.forward(&Container::itemfun, &Item::fred, 1); + + // This call compiles with a warning and segvs on execution if using + // -O1 or greater with 4.3.*. 4.2.* is correct. + void (Container::*itemfunptr)(itemfun, int) = +&Container::itemfun; + t.forward(itemfunptr, &Item::fred, 1); + + return 0; +} + diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index fbfcbf2..c308a35 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1165,12 +1165,18 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type) if (TREE_CODE (inner_type) != TREE_CODE (outer_type)) return false; - /* ??? Add structural equivalence check. */ + /* ??? This seems to be necessary even for aggregates that don't + have TYPE_STRUCTURAL_EQUALITY_P set. */ /* ??? This should eventually just return false. */ return lang_hooks.types_compatible_p (inner_type, outer_type); } - + /* Also for functions and possibly other types with + TYPE_STRUCTURAL_EQUALITY_P set. */ + else if (TYPE_STRUCTURAL_EQUALITY_P (inner_type) + && TYPE_STRUCTURAL_EQUALITY_P (outer_type)) + return lang_hooks.types_compatible_p (inner_type, outer_type); + return false; } -- 2.7.4