1 // PR tree-optimization/56381
2 // { dg-do compile { target c++11 } }
3 // { dg-options "-O2 -w" }
4 
5 template <class>
6 class intrusive_ptr {};
7 class BasicReferenceCounted
8 {
9 };
10 template <class T>
11 class ReferenceCountingPointer : intrusive_ptr <T>
12 {
13 };
14 typedef BasicReferenceCounted ReferenceCountedInConditions;
15 class PointTag;
16 template <typename T, typename>
17 struct PreciseFloatType
18 {
19   typedef T Type;
20 };
21 template <typename T, int N>
22 struct ExtVecTraits
23 {
24   typedef T __attribute__ ((vector_size (N * sizeof (T)))) type;
25 };
26 template <typename T, int N>
27 using ExtVec = typename ExtVecTraits <T, N>::type;
28 template <typename T> using Vec4 = ExtVec <T, 4>;
29 template <typename Vec>
cross3(Vec x,Vec y)30 Vec cross3 (Vec x, Vec y)
31 {
32   Vec x1200 = (Vec) { x[2], x[0] };
33   Vec y2010 { y[2], y[0], y[1], y[0] };
34   Vec x2010 = (Vec) { x[2], x[0], x[1], x[0] };
35   Vec y1200 = (Vec) { y[1], y[0] };
36   return x1200 * y2010 - x2010 * y1200;
37 }
38 template <typename T>
39 struct Rot3
40 {
41   typedef Vec4 <T> Vec;
42   Vec axis[3];
43 };
44 class Basic2DVector
45 {
46 };
47 template <typename T>
48 struct Basic3DVector
49 {
50   typedef Vec4 <T> MathVector;
Basic3DVectorBasic3DVector51   Basic3DVector (MathVector iv) : v { (iv[0]), (iv[1]), (iv[2]), (iv[3]) } {}
mag2Basic3DVector52   T mag2 () {}
unitBasic3DVector53   Basic3DVector unit ()
54   {
55     T my_mag = mag2 ();
56     return (my_mag) ? (*this) * (T () / (my_mag)) : *this;
57   }
58   Basic3DVector
crossBasic3DVector59   cross (Basic3DVector lh) { return cross3 (v, lh.v); }
60   Vec4 <T> v;
61 };
62 template <class T>
63 Basic3DVector <T> operator * (Basic3DVector <T>, T);
64 template <class T, class, class>
65 struct PV3DBase
66 {
67   typedef Basic3DVector <T> BasicVectorType;
68   template <class U>
PV3DBasePV3DBase69   PV3DBase (Basic3DVector <U> v) : theVector (v) {}
basicVectorPV3DBase70   BasicVectorType basicVector () { return theVector; }
71   T x ();
72   T y ();
73   BasicVectorType theVector;
74 };
75 class VectorTag;
76 template <class T, class FrameTag>
77 struct Vector3DBase:public PV3DBase <T, VectorTag, FrameTag>
78 {
79   typedef PV3DBase <T, VectorTag, FrameTag> BaseClass;
80   template <class U>
Vector3DBaseVector3DBase81   Vector3DBase (Basic3DVector <U> v) : BaseClass (v) {}
unitVector3DBase82   Vector3DBase unit () { return (this->basicVector ().unit ()); }
83   template <class U>
crossVector3DBase84   Vector3DBase <typename PreciseFloatType <T, U>::Type, FrameTag> cross (Vector3DBase <U, FrameTag> v)
85   {
86     return (this->theVector.cross (v.basicVector ()));
87   }
88 };
89 template <class T, class FrameTag>
90 class Point3DBase : public PV3DBase <T, PointTag, FrameTag>
91 {
92 };
93 template <typename T, typename U, class Frame>
94 Vector3DBase <typename PreciseFloatType <T, U>::Type, Frame> operator - (Point3DBase <T, Frame>, Point3DBase <U, Frame>);
95 class GlobalTag;
96 template <class T>
97 struct TkRotation
98 {
99   typedef Vector3DBase <T, GlobalTag> GlobalVector;
TkRotationTkRotation100   TkRotation (GlobalVector aX, GlobalVector aY)
101   {
102     GlobalVector uX = aX.unit ();
103     GlobalVector uY = aY.unit ();
104     GlobalVector uZ (uX.cross (uY));
105     rot.axis[2] = uZ.basicVector ().v;
106   }
107   Basic3DVector <T> z ();
108   Rot3 <T> rot;
109 };
110 template <class T>
111 struct GloballyPositioned
112 {
113   typedef Point3DBase <T, GlobalTag> PositionType;
114   typedef TkRotation <T> RotationType;
115   typedef Point3DBase <T, GlobalTag> GlobalPoint;
116   typedef Vector3DBase <T, GlobalTag> GlobalVector;
iniPhiGloballyPositioned117   T iniPhi () { return 999.9978; }
GloballyPositionedGloballyPositioned118   GloballyPositioned (PositionType pos, RotationType rot) : thePos (pos), theRot (rot) { resetCache (); }
119   PositionType position () const;
120   RotationType rotation () const;
121   PositionType thePos;
122   RotationType theRot;
resetCacheGloballyPositioned123   void resetCache ()
124   {
125     if ((thePos.x () == 0.) && (thePos.y () == 0.))
126       thePhi = 0.;
127     else
128       thePhi = iniPhi ();
129   }
130   T thePhi;
131 };
132 class Plane;
133 using TangentPlane = Plane;
134 struct Surface : public GloballyPositioned <float>, ReferenceCountedInConditions
135 {
136   typedef GloballyPositioned <float> Base;
SurfaceSurface137   Surface (PositionType pos, RotationType rot):
138   Base (pos, rot) {}
139 };
140 struct Plane : Surface
141 {
142   template <typename ... Args>
PlanePlane143   Plane (Args ... args):
144   Surface ((args) ...) {}
145 };
146 class Cylinder : Surface
147 {
148   void tangentPlane (const GlobalPoint &) const;
149 };
150 void
tangentPlane(const GlobalPoint & aPoint)151 Cylinder::tangentPlane (const GlobalPoint & aPoint) const
152 {
153   GlobalVector yPlane (rotation ().z ());
154   GlobalVector xPlane (yPlane.cross (aPoint - position ()));
155   new TangentPlane (aPoint, RotationType (xPlane, yPlane));
156 }
157