// { dg-do run } // PRMS Id: 6275 // Bug: unification fails for call to find_parameter_in_stack. #include #include const int max_stack_size = 20; template class Stack { private: T objects[max_stack_size]; int nobjects; public: Stack(): nobjects(0) {} void push(const T&a) { if (nobjects >= max_stack_size) { fprintf(stderr,"Stack: overflow\n"); abort(); } objects[nobjects++] = a; } T pop() { if (!nobjects) { fprintf(stderr,"Stack: underflow\n"); abort(); } nobjects -= 1; T result = objects[nobjects]; return result; } T top() const { if (!nobjects) { fprintf(stderr,"Stack: underflow\n"); abort(); } return objects[nobjects - 1]; } int n() const { return nobjects; } T operator[](int i) { return objects[i]; } }; template class Parameter { T parameter_; int is_set_; int overrides_; public: Parameter(): is_set_(0), overrides_(0) {} void set(const T& a) { parameter_ = a; is_set_ = 1; } void override(int overrides = 1) { overrides_ = overrides; } const T& value() const { return parameter_; } int overrides() const { return overrides_; } int is_set() const { return is_set_; } }; template T2 find_parameter_in_stack(Stack& stack, Parameter& (T1::*access)()) { T2 result; int have_result = 0; for (int i=stack.n()-1; i>=0; i--) { if ((stack[i].*access)().is_set()) { if (!have_result || (stack[i].*access)().overrides()) { result = (stack[i].*access)().value(); have_result = 1; } } } return result; } class A { private: Parameter a_; public: A() { } Parameter& a() { return a_; } }; int main(int, char**) { Stack A_stack; A a1; A a2; a1.a().set(1); a2.a().set(2); A_stack.push(a1); A_stack.push(a2); int val = find_parameter_in_stack(A_stack, &A::a); printf("val = %d\n", val); if (val != 2) return 1; A_stack.pop(); A_stack.pop(); a1.a().override(); A_stack.push(a1); A_stack.push(a2); val = find_parameter_in_stack(A_stack, &A::a); printf("val = %d\n", val); if (val != 1) return 1; return 0; }