From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/testsuite/g++.dg/opt/pmf1.C | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 gcc/testsuite/g++.dg/opt/pmf1.C (limited to 'gcc/testsuite/g++.dg/opt/pmf1.C') diff --git a/gcc/testsuite/g++.dg/opt/pmf1.C b/gcc/testsuite/g++.dg/opt/pmf1.C new file mode 100644 index 000000000..428e7530b --- /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; +} + -- cgit v1.2.3