summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/init/new19.C
blob: a25be7da7e57bcab711636c197af4b4c176add63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// { dg-do compile }
// { dg-options "-O2 -fstrict-aliasing -fdump-tree-pre-details" }

// Make sure we hoist invariants out of the loop even in the presence
// of placement new.  This is similar to code in tramp3d.

typedef __SIZE_TYPE__ size_t;

inline void* operator new(size_t, void* __p) throw() { return __p; }

template <class T, int D>
class Vector
{
public:
   Vector()
   {
     for (int i = 0; i < D; ++i)
        new (&x_m[i]) T();
   }
   T& operator[](int i) { return x_m[i]; }

private:
   T x_m[D];
};

struct sia
{
  int ai[3];
};

struct s
{
  struct si
  {
    sia* p;
  } asi[3];
  float* pd;
};

class c
{
  int foo(int, int, int);
  s sm;
};


extern void bar(Vector<float, 3>*, int);
int c::foo(int f1, int f2, int f3)
{
  float sum = 0;
  for (int i = 0; i < 3; ++i)
    {
      for (int j = 0; j < 3; ++j)
	{
	  Vector<float, 3> v;
	  v[0] = 1.0;
	  v[1] = 2.0;
	  v[2] = 3.0;
	  for (int k = 0; k < 3; ++k)
	    {
	      float f = (f1 * this->sm.asi[0].p->ai[0]
			 + f2 * this->sm.asi[1].p->ai[0]
			 + f3 * this->sm.asi[2].p->ai[0]);
	      sum += f * v[k];
	    }
	  *this->sm.pd = sum;
	}
    }
  return sum;
}

// { dg-final { scan-tree-dump "Replaced.*->ai\\\[0\\\]" "pre" } }
// { dg-final { cleanup-tree-dump "pre" } }