diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/opt/pmf1.C | |
download | cbb-gcc-4.6.4-15d2061ac0796199866debe9ac87130894b0cdd3.tar.bz2 cbb-gcc-4.6.4-15d2061ac0796199866debe9ac87130894b0cdd3.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
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.
Diffstat (limited to 'gcc/testsuite/g++.dg/opt/pmf1.C')
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pmf1.C | 76 |
1 files changed, 76 insertions, 0 deletions
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 <class Derived> +struct WorldObject { + template <typename memfunT, typename arg1T, typename arg2T> + void forward(memfunT memfun, arg1T arg1, arg2T arg2) { + Derived* obj = static_cast<Derived*>(this); + (obj->*memfun)(arg1, arg2); + } +}; + +struct Item { + void fred(int a) { + printf ("a=%d\n", a); + } +}; + +struct Container : public WorldObject<Container> { + Item item; + template <typename itemfunT, typename arg1T> + 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<itemfun,int>, &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<itemfun,int>; + t.forward(itemfunptr, &Item::fred, 1); + + return 0; +} + |