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