2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / testsuite / g++.dg / opt / stack1.C
blob7fac18dac03d22629a51347e2aa3a223542c6684
1 // PR optimization/11198
2 // Origin: Joerg Walter <jhr.walter@t-online.de>
3 // Reduced testcase by: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
4 //                      Wolfgang Bangerth <bangerth@ticam.utexas.edu>
6 // The compiler used to allocate the same stack slot for two aggregates,
7 // overlooking that assignments to members given the same address on the
8 // stack may not alias and thus may be reordered by the scheduling passes.
10 // { dg-do run }
11 // { dg-options "-O2 -frename-registers" }
14 double zero_;
16 inline const int&
17 min(const int& a, const int& b) {
18   if (b < a) return b; return a;
21 struct barrier { barrier () {} };
23 template <typename=void> struct unbounded_array {
24     inline unbounded_array (): data_ (new double [9]) {}
25     inline double& operator [] (int i) { return data_ [i]; }
26     double* data_;
29 inline int element (int i, int j) {
30   return i + j;
33 template <typename=void>
34 struct matrix {
35     inline matrix () : size2_ (3) {}
37     inline unbounded_array<> &data () { return data_; }
39     inline double& el (int i, int j) {
40       int dead1 = j;
41       int dead2 = 1 + i - j;
42       if (j < size2_ && i-j < 2)
43         return data () [element (j,i-j+1)];
44       barrier ();
45       return zero_;
46     }
48     struct iterator2;
50     inline iterator2 find () {
51       return iterator2 (*this);
52     }
54     struct iterator1 {
55         inline iterator1 (matrix *m):
56                         dead1 (m), i (0) {}
57         void *dead1;
58         int i;
59         int dead2;
60     };
62     const int size2_;
63     unbounded_array<> data_;
67 template<typename=void>
68 struct adaptor {
69     adaptor (matrix<> &m) : m(&m), upper_ (1) {}
71     int size1 () const;
72     int size2 () const     { return 3; }
73     int lower () const     { return 1; }
74     int upper () const     { return upper_; }
75     matrix<> &data () { return *m; }
77     double& el (int i, int j) {
78       int dead1, dead2;
79       if (j < size2 () && i-j < 1)
80         return data ().el (i, j);
82       barrier ();
83       return zero_;
84     }
86     struct a_iterator2;
88     struct a_iterator1 {
89         a_iterator1 (adaptor &a, const matrix<>::iterator1 &it1):
90                         a (&a), dead1 (it1) {}
92         a_iterator2 begin () const {
93           return a_iterator2(*a);
94         }
95         adaptor *a;     
96         matrix<>::iterator1 dead1;
97     };
99     struct a_iterator2 {
100         a_iterator2 (adaptor &a) : a (&a) {}
102         double& f () const {
103           int i = 0;
104           int l = a->upper () + i;
105           int q = a->size2 ();
106           if (0 < q &&
107               l < a->lower () + 1 + a->upper ())
108             return a->m->el(0,0);
110           return a->el (i, 0);
111         }
113         adaptor *a;
114     };
116     matrix<> *m;
117     int upper_;
120 void matrix_swap (adaptor<> &bam1, adaptor<> &bam2)
122   adaptor<>::a_iterator1 it1 (bam1,matrix<>::iterator1(bam1.m)),
123                          it2 (bam2,matrix<>::iterator1(bam2.m));
124   int dead;
125   double x = it1.begin().f();
126   it2.begin().f() = x;
129 int main ()
131   matrix<> m1,m2;
132   adaptor<> bam1 (m1), bam2 (m2);
133   matrix_swap (bam1, bam2);
134   return 0;