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
8const int max_stack_size = 20;
9
10template <class T>
11class Stack {
12  private:
13    T objects[max_stack_size];
14    int nobjects;
15  public:
16    Stack(): nobjects(0) {}
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      }
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      }
33    T top() const {
34        if (!nobjects) {
35            fprintf(stderr,"Stack: underflow\n");
36            abort();
37          }
38        return objects[nobjects - 1];
39      }
40    int n() const { return nobjects; }
41    T operator[](int i) { return objects[i]; }
42};
43
44template <class T>
45class Parameter {
46    T parameter_;
47    int is_set_;
48    int overrides_;
49  public:
50    Parameter(): is_set_(0), overrides_(0) {}
51    void set(const T& a) { parameter_ = a; is_set_ = 1; }
52    void override(int overrides = 1) { overrides_ = overrides; }
53    const T& value() const { return parameter_; }
54    int overrides() const { return overrides_; }
55    int is_set() const { return is_set_; }
56};
57
58template <class T1, class T2>
59T2
60find_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
75class A {
76  private:
77    Parameter<int> a_;
78  public:
79    A() { }
80    Parameter<int>& a() { return a_; }
81};
82
83int
84main(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