summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0258-PR-debug-48967.patch
blob: c926a5971b9ce53f3302bd44ae7f09321f59693a (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
From 5581111b5be72638aebb478c70c2bafc0abd04e2 Mon Sep 17 00:00:00 2001
From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 12 May 2011 11:59:32 +0000
Subject: [PATCH] 	PR debug/48967
 	* var-tracking.c (use_narrower_mode_test) <case REG>: Return 1
 	if validate_subreg fails.

	* g++.dg/opt/pr48967.C: New test.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173702 138bc75d-0d04-0410-961f-82ee72b054a4

index 5e328ff..be253f4 100644
new file mode 100644
index 0000000..db2ea54
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr48967.C
@@ -0,0 +1,98 @@
+// PR debug/48967
+// { dg-do compile }
+// { dg-options "-g -O2" }
+
+template <typename> struct A;
+template <typename T> struct A <T *>
+{
+  typedef T ref;
+};
+template <typename T, typename> struct B
+{
+  typedef A <T> t;
+  typedef typename t::ref ref;
+  ref operator * () { return ref (); }
+};
+template <typename T> struct I
+{
+  typedef T *cp;
+  template <typename T1> struct J
+  {
+    typedef I <T1> other;
+  };
+};
+template <typename T> struct S : public I <T>
+{
+};
+template <typename T, typename _A> struct E
+{
+  typedef typename _A::template J <T>::other at;
+};
+template <typename T, typename _A = S <T> > struct D
+{
+  typedef E <T, _A> _Base;
+  typedef typename _Base::at at;
+  typedef typename at::cp cp;
+  typedef B <cp, D> H;
+};
+template <class T> struct F
+{
+  T *operator -> () { return __null; }
+};
+template <typename T> long
+lfloor (T x)
+{
+  return static_cast <long>(x) - (x && x != static_cast <long>(x));
+}
+template <typename T> long
+lround (T x)
+{
+  return lfloor (x - 0.5) + 1;
+}
+class M;
+template <typename> class P;
+typedef P <M> Q;
+template <typename> struct P
+{
+  float x ();
+};
+struct CV
+{
+  Q c;
+};
+struct C
+{
+  void foo (const CV &) const;
+  class O;
+  typedef D <F <O> > R;
+  R n;
+};
+struct S3
+{
+  S3 (int, int);
+};
+struct S2
+{
+  S3 sx, sy;
+  S2 (int x = 0, int y = 0, int s = 0, int t = 0) : sx (x, y), sy (s, t) {}
+};
+template <typename> struct N
+{
+  int bar ();
+};
+struct C::O
+{
+  N <float> o;
+  void foo (CV r, int)
+  {
+    Q c = r.c;
+    float t = 0.5 * (o.bar ());
+    S2 (lround (c.x ()), t);
+  }
+};
+void
+C::foo (const CV &w) const
+{
+  R::H m;
+  (*m)->foo (w, 8);
+}
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 548afbc..b7ba0b9 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -739,6 +739,10 @@ use_narrower_mode_test (rtx *loc, void *data)
     case REG:
       if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode))
 	return 1;
+      if (!validate_subreg (GET_MODE (subreg), GET_MODE (*loc),
+			    *loc, subreg_lowpart_offset (GET_MODE (subreg),
+							 GET_MODE (*loc))))
+	return 1;
       return -1;
     case PLUS:
     case MINUS:
-- 
1.7.0.4