annotate gcc/testsuite/g++.dg/opt/pmf1.C @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // PR c++/37016
kono
parents:
diff changeset
2 // { dg-do run }
kono
parents:
diff changeset
3 // { dg-options "-O2 -Wall" }
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 /*
kono
parents:
diff changeset
6 Basic design concept is that WorldObject implements remote method call
kono
parents:
diff changeset
7 functionality using the "curiously recurring template pattern" to enable
kono
parents:
diff changeset
8 forwarding calls from the generic base class that implements the transport
kono
parents:
diff changeset
9 layer to the derived class.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 The specific failure was in forwarding calls to items in a container.
kono
parents:
diff changeset
12 This is emulated here by wrapping a single item.
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 In the main program there are two forms of the call. In the last
kono
parents:
diff changeset
15 (uncommented) form the member function pointer is for clarity
kono
parents:
diff changeset
16 assigned to a variable (itemfunptr) before making the call.
kono
parents:
diff changeset
17 With 4.3.0 and 4.3.1 this code compiles incorrectly with -O1 or greater
kono
parents:
diff changeset
18 to produce this warning
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 reproduce.cc: In function ‘int main()’:
kono
parents:
diff changeset
21 reproduce.cc:26: warning: ‘itemfunptr.void (Container::*)(void
kono
parents:
diff changeset
22 (Item::*)(int), int)::__pfn’ is used uninitialized in this function
kono
parents:
diff changeset
23 reproduce.cc:47: note: ‘itemfunptr.void (Container::*)(void (Item::*)(int),
kono
parents:
diff changeset
24 int)::__pfn’ was declared here
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 and the resulting executable segvs. It works correctly with -O0.
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 With 4.2.3 and earlier it works correctly with optimization.
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 In the first (commented out) form of the call in the main program
kono
parents:
diff changeset
31 we directly refer to desired member function. This compiles
kono
parents:
diff changeset
32 and executes correctly with all tested versions.
kono
parents:
diff changeset
33 */
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 extern "C" int printf (const char *, ...);
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 template <class Derived>
kono
parents:
diff changeset
38 struct WorldObject {
kono
parents:
diff changeset
39 template <typename memfunT, typename arg1T, typename arg2T>
kono
parents:
diff changeset
40 void forward(memfunT memfun, arg1T arg1, arg2T arg2) {
kono
parents:
diff changeset
41 Derived* obj = static_cast<Derived*>(this);
kono
parents:
diff changeset
42 (obj->*memfun)(arg1, arg2);
kono
parents:
diff changeset
43 }
kono
parents:
diff changeset
44 };
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 struct Item {
kono
parents:
diff changeset
47 void fred(int a) {
kono
parents:
diff changeset
48 printf ("a=%d\n", a);
kono
parents:
diff changeset
49 }
kono
parents:
diff changeset
50 };
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 struct Container : public WorldObject<Container> {
kono
parents:
diff changeset
53 Item item;
kono
parents:
diff changeset
54 template <typename itemfunT, typename arg1T>
kono
parents:
diff changeset
55 void itemfun(itemfunT itemfun, int a) {
kono
parents:
diff changeset
56 (item.*itemfun)(a);
kono
parents:
diff changeset
57 }
kono
parents:
diff changeset
58 };
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 int main() {
kono
parents:
diff changeset
61 typedef void (Item::*itemfun)(int);
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 Container t;
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 // This call compiles and executes correctly with all versions tested
kono
parents:
diff changeset
66 //t.forward(&Container::itemfun<itemfun,int>, &Item::fred, 1);
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 // This call compiles with a warning and segvs on execution if using
kono
parents:
diff changeset
69 // -O1 or greater with 4.3.*. 4.2.* is correct.
kono
parents:
diff changeset
70 void (Container::*itemfunptr)(itemfun, int) =
kono
parents:
diff changeset
71 &Container::itemfun<itemfun,int>;
kono
parents:
diff changeset
72 t.forward(itemfunptr, &Item::fred, 1);
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 return 0;
kono
parents:
diff changeset
75 }
kono
parents:
diff changeset
76