diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 32ac06b6c1c778b20a3c35f3d0c9bc6c93a12647..cbb10dab60468e394719c75a743cc743424e9364 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-02 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/50672 + * g++.dg/pr50672.C: New test. + 2011-11-02 Uros Bizjak <ubizjak@gmail.com> * gcc.target/i386/avx-cvt-2.c (dg-options): Add -mtune=generic. diff --git a/gcc/testsuite/g++.dg/pr50672.C b/gcc/testsuite/g++.dg/pr50672.C new file mode 100644 index 0000000000000000000000000000000000000000..fb310082edc92eb8c5a9f36024672d5ba370c92a --- /dev/null +++ b/gcc/testsuite/g++.dg/pr50672.C @@ -0,0 +1,101 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-tail-merge" } */ +typedef int BoxCoordinate; +typedef int BoxDimension; +const BoxDimension X = 0; +const BoxDimension Y = 1; +const BoxDimension NDimensions = 2; +class BoxPoint { + BoxCoordinate point[NDimensions]; +public: + bool isValid() const; + void operator += (const BoxPoint& p) { + if (isValid() && p.isValid()) { + point[X] += p.point[X]; + } + } + const BoxCoordinate& operator [] (const BoxDimension& dimension) const { + return point[dimension]; + } +}; +class BoxRegion { +public: + BoxCoordinate& origin(BoxDimension d) const; + BoxCoordinate& space(BoxDimension d) const; +}; +inline bool operator <= (const BoxPoint& p, const BoxRegion& r) { + for (BoxDimension d = X; + d <= Y; + d++) if (p[d] < r.origin(d) || p[d] >= r.origin(d) + r.space(d)) +return false; + return true; +} +typedef struct _WidgetRec *Widget; +struct GraphGC { + BoxPoint offsetIfSelected; +}; +class GraphNode; +class GraphEdge { +public: + GraphNode *from() const; + GraphNode *to() const; +}; +class LineGraphEdge: public GraphEdge { +protected: + virtual void drawLine(Widget w, const GraphGC& gc) const; + void _print(const GraphGC &gc) const; +}; +class ArcGraphEdge: public LineGraphEdge { + static bool center(const BoxPoint& p1, const BoxPoint& p2, + const BoxPoint& p3, double& x, double& y); + void makeLine(Widget w, const GraphGC& gc) const; +}; +class GraphNode { +public: + bool& selected(); + GraphEdge *firstTo() const; + GraphEdge *nextTo(GraphEdge *ref) const; + virtual const BoxPoint& pos() const = 0; + virtual const BoxRegion& region(const GraphGC& gc) const = 0; + virtual bool isHint() const; +}; +class PosGraphNode: public GraphNode { }; +class RegionGraphNode: public PosGraphNode { }; +class HintGraphNode: public RegionGraphNode { }; +void ArcGraphEdge::makeLine(Widget w, const GraphGC& gc) const { + HintGraphNode *arc_hint = 0; + RegionGraphNode *arc_from = 0; + RegionGraphNode *arc_to = 0; + bool make_arc = true; + if (from()->isHint() && to()->isHint()) { + make_arc = false; + } + else if (from()->isHint() && from()->firstTo() != 0) { + if (arc_hint == 0 || arc_from == 0 || arc_to == 0 + || arc_hint->nextTo(arc_hint->firstTo()) != 0) { + make_arc = false; + } + } + if (!make_arc) { + if (w != 0) LineGraphEdge::drawLine(w, gc); + else LineGraphEdge::_print(gc); + return; + } + BoxPoint pos_from = arc_from->pos(); + BoxRegion region_from = arc_from->region(gc); + BoxPoint pos_to = arc_to->pos(); + BoxRegion region_to = arc_to->region(gc); + BoxPoint pos_hint = arc_hint->pos(); + if (arc_hint->selected()) { + pos_hint += gc.offsetIfSelected; + } + if (pos_hint <= region_from || pos_hint <= region_to) { + return; + } + double cx, cy; + bool ok = center(pos_from, pos_hint, pos_to, cx, cy); + if (!ok) { + if (w != 0) LineGraphEdge::drawLine(w, gc); + else LineGraphEdge::_print(gc); + } +}