1 // { dg-do run }
2 // PRMS Id: 6275
3 // Bug: unification fails for call to find_parameter_in_stack.
4
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 const int max_stack_size = 20;
9
10 template <class T>
11 class Stack {
12 private:
13 T objects[max_stack_size];
14 int nobjects;
15 public:
Stack()16 Stack(): nobjects(0) {}
push(const T & a)17 void push(const T&a) {
18 if (nobjects >= max_stack_size) {
19 fprintf(stderr,"Stack: overflow\n");
20 abort();
21 }
22 objects[nobjects++] = a;
23 }
pop()24 T pop() {
25 if (!nobjects) {
26 fprintf(stderr,"Stack: underflow\n");
27 abort();
28 }
29 nobjects -= 1;
30 T result = objects[nobjects];
31 return result;
32 }
top()33 T top() const {
34 if (!nobjects) {
35 fprintf(stderr,"Stack: underflow\n");
36 abort();
37 }
38 return objects[nobjects - 1];
39 }
n()40 int n() const { return nobjects; }
41 T operator[](int i) { return objects[i]; }
42 };
43
44 template <class T>
45 class Parameter {
46 T parameter_;
47 int is_set_;
48 int overrides_;
49 public:
Parameter()50 Parameter(): is_set_(0), overrides_(0) {}
set(const T & a)51 void set(const T& a) { parameter_ = a; is_set_ = 1; }
52 void override(int overrides = 1) { overrides_ = overrides; }
value()53 const T& value() const { return parameter_; }
overrides()54 int overrides() const { return overrides_; }
is_set()55 int is_set() const { return is_set_; }
56 };
57
58 template <class T1, class T2>
59 T2
find_parameter_in_stack(Stack<T1> & stack,Parameter<T2> & (T1::* access)())60 find_parameter_in_stack(Stack<T1>& stack, Parameter<T2>& (T1::*access)())
61 {
62 T2 result;
63 int have_result = 0;
64 for (int i=stack.n()-1; i>=0; i--) {
65 if ((stack[i].*access)().is_set()) {
66 if (!have_result || (stack[i].*access)().overrides()) {
67 result = (stack[i].*access)().value();
68 have_result = 1;
69 }
70 }
71 }
72 return result;
73 }
74
75 class A {
76 private:
77 Parameter<int> a_;
78 public:
A()79 A() { }
a()80 Parameter<int>& a() { return a_; }
81 };
82
83 int
main(int,char **)84 main(int, char**)
85 {
86 Stack<A> A_stack;
87 A a1;
88 A a2;
89 a1.a().set(1);
90 a2.a().set(2);
91 A_stack.push(a1);
92 A_stack.push(a2);
93
94 int val = find_parameter_in_stack(A_stack, &A::a);
95
96 printf("val = %d\n", val);
97 if (val != 2)
98 return 1;
99
100 A_stack.pop();
101 A_stack.pop();
102
103 a1.a().override();
104
105 A_stack.push(a1);
106 A_stack.push(a2);
107
108 val = find_parameter_in_stack(A_stack, &A::a);
109
110 printf("val = %d\n", val);
111 if (val != 1)
112 return 1;
113
114 return 0;
115 }
116