diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0327-PR-c-49136.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0327-PR-c-49136.patch | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0327-PR-c-49136.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0327-PR-c-49136.patch new file mode 100644 index 0000000000..dcf00aece5 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0327-PR-c-49136.patch | |||
@@ -0,0 +1,142 @@ | |||
1 | From aa15fbe864f58be935154f76f8ebf144988e7746 Mon Sep 17 00:00:00 2001 | ||
2 | From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Wed, 25 May 2011 07:03:25 +0000 | ||
4 | Subject: [PATCH] PR c++/49136 | ||
5 | * semantics.c (cxx_eval_bit_field_ref): Handle the | ||
6 | case when BIT_FIELD_REF doesn't cover only a single field. | ||
7 | |||
8 | * g++.dg/cpp0x/constexpr-bitfield2.C: New test. | ||
9 | * g++.dg/cpp0x/constexpr-bitfield3.C: New test. | ||
10 | |||
11 | |||
12 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174169 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
13 | |||
14 | index bd33bac..6207b12 100644 | ||
15 | --- a/gcc/cp/semantics.c | ||
16 | +++ b/gcc/cp/semantics.c | ||
17 | @@ -6391,6 +6391,9 @@ cxx_eval_bit_field_ref (const constexpr_call *call, tree t, | ||
18 | bool *non_constant_p) | ||
19 | { | ||
20 | tree orig_whole = TREE_OPERAND (t, 0); | ||
21 | + tree retval, fldval, utype, mask; | ||
22 | + bool fld_seen = false; | ||
23 | + HOST_WIDE_INT istart, isize; | ||
24 | tree whole = cxx_eval_constant_expression (call, orig_whole, | ||
25 | allow_non_constant, addr, | ||
26 | non_constant_p); | ||
27 | @@ -6411,12 +6414,47 @@ cxx_eval_bit_field_ref (const constexpr_call *call, tree t, | ||
28 | return t; | ||
29 | |||
30 | start = TREE_OPERAND (t, 2); | ||
31 | + istart = tree_low_cst (start, 0); | ||
32 | + isize = tree_low_cst (TREE_OPERAND (t, 1), 0); | ||
33 | + utype = TREE_TYPE (t); | ||
34 | + if (!TYPE_UNSIGNED (utype)) | ||
35 | + utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1); | ||
36 | + retval = build_int_cst (utype, 0); | ||
37 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value) | ||
38 | { | ||
39 | - if (bit_position (field) == start) | ||
40 | + tree bitpos = bit_position (field); | ||
41 | + if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1)) | ||
42 | return value; | ||
43 | + if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE | ||
44 | + && TREE_CODE (value) == INTEGER_CST | ||
45 | + && host_integerp (bitpos, 0) | ||
46 | + && host_integerp (DECL_SIZE (field), 0)) | ||
47 | + { | ||
48 | + HOST_WIDE_INT bit = tree_low_cst (bitpos, 0); | ||
49 | + HOST_WIDE_INT sz = tree_low_cst (DECL_SIZE (field), 0); | ||
50 | + HOST_WIDE_INT shift; | ||
51 | + if (bit >= istart && bit + sz <= istart + isize) | ||
52 | + { | ||
53 | + fldval = fold_convert (utype, value); | ||
54 | + mask = build_int_cst_type (utype, -1); | ||
55 | + mask = fold_build2 (LSHIFT_EXPR, utype, mask, | ||
56 | + size_int (TYPE_PRECISION (utype) - sz)); | ||
57 | + mask = fold_build2 (RSHIFT_EXPR, utype, mask, | ||
58 | + size_int (TYPE_PRECISION (utype) - sz)); | ||
59 | + fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask); | ||
60 | + shift = bit - istart; | ||
61 | + if (BYTES_BIG_ENDIAN) | ||
62 | + shift = TYPE_PRECISION (utype) - shift - sz; | ||
63 | + fldval = fold_build2 (LSHIFT_EXPR, utype, fldval, | ||
64 | + size_int (shift)); | ||
65 | + retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval); | ||
66 | + fld_seen = true; | ||
67 | + } | ||
68 | + } | ||
69 | } | ||
70 | - gcc_unreachable(); | ||
71 | + if (fld_seen) | ||
72 | + return fold_convert (TREE_TYPE (t), retval); | ||
73 | + gcc_unreachable (); | ||
74 | return error_mark_node; | ||
75 | } | ||
76 | |||
77 | new file mode 100644 | ||
78 | index 0000000..531bf31 | ||
79 | --- /dev/null | ||
80 | +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield2.C | ||
81 | @@ -0,0 +1,19 @@ | ||
82 | +// PR c++/49136 | ||
83 | +// { dg-do compile } | ||
84 | +// { dg-options "-std=c++0x" } | ||
85 | + | ||
86 | +struct day | ||
87 | +{ | ||
88 | + unsigned d : 5; | ||
89 | + unsigned n : 3; | ||
90 | + constexpr explicit day (int dd) : d(dd), n(7) {} | ||
91 | +}; | ||
92 | + | ||
93 | +struct date { | ||
94 | + int d; | ||
95 | + constexpr date (day dd) : d(dd.n != 7 ? 7 : dd.d) {} | ||
96 | +}; | ||
97 | + | ||
98 | +constexpr day d(0); | ||
99 | +constexpr date dt(d); | ||
100 | +static_assert (dt.d == 0, "Error"); | ||
101 | diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield3.C | ||
102 | new file mode 100644 | ||
103 | index 0000000..b0ecbfb | ||
104 | --- /dev/null | ||
105 | +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-bitfield3.C | ||
106 | @@ -0,0 +1,33 @@ | ||
107 | +// PR c++/49136 | ||
108 | +// { dg-do compile } | ||
109 | +// { dg-options "-std=c++0x" } | ||
110 | + | ||
111 | +struct S | ||
112 | +{ | ||
113 | + unsigned : 1; unsigned s : 27; unsigned : 4; | ||
114 | + constexpr S (unsigned int x) : s(x) {} | ||
115 | +}; | ||
116 | + | ||
117 | +template <typename S> | ||
118 | +struct T | ||
119 | +{ | ||
120 | + unsigned int t; | ||
121 | + constexpr T (S s) : t(s.s != 7 ? 0 : s.s) {} | ||
122 | + constexpr T (S s, S s2) : t(s.s != s2.s ? 0 : s.s) {} | ||
123 | +}; | ||
124 | + | ||
125 | +constexpr S s (7), s2 (7); | ||
126 | +constexpr T<S> t (s), t2 (s, s2); | ||
127 | +static_assert (t.t == 7, "Error"); | ||
128 | +static_assert (t2.t == 7, "Error"); | ||
129 | + | ||
130 | +struct U | ||
131 | +{ | ||
132 | + int a : 1; int s : 1; | ||
133 | + constexpr U (int x, int y) : a (x), s (y) {} | ||
134 | +}; | ||
135 | + | ||
136 | +constexpr U u (0, -1), u2 (-1, -1); | ||
137 | +constexpr T<U> t3 (u), t4 (u, u2); | ||
138 | +static_assert (t3.t == 0, "Error"); | ||
139 | +static_assert (t4.t == -1, "Error"); | ||
140 | -- | ||
141 | 1.7.0.4 | ||
142 | |||