diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0342-PR-c-44311.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0342-PR-c-44311.patch | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0342-PR-c-44311.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0342-PR-c-44311.patch new file mode 100644 index 0000000000..6ebd511869 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0342-PR-c-44311.patch | |||
@@ -0,0 +1,125 @@ | |||
1 | From f6945c41cc9a66590ea92a1d0d7c862d14ccd23c Mon Sep 17 00:00:00 2001 | ||
2 | From: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Wed, 25 May 2011 20:30:21 +0000 | ||
4 | Subject: [PATCH] PR c++/44311 | ||
5 | * decl.c (case_conversion): New. | ||
6 | (finish_case_label): Use it. | ||
7 | |||
8 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174237 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
9 | |||
10 | index cc7a155..de53541 100644 | ||
11 | --- a/gcc/cp/decl.c | ||
12 | +++ b/gcc/cp/decl.c | ||
13 | @@ -2920,6 +2920,28 @@ pop_switch (void) | ||
14 | free (cs); | ||
15 | } | ||
16 | |||
17 | +/* Convert a case constant VALUE in a switch to the type TYPE of the switch | ||
18 | + condition. Note that if TYPE and VALUE are already integral we don't | ||
19 | + really do the conversion because the language-independent | ||
20 | + warning/optimization code will work better that way. */ | ||
21 | + | ||
22 | +static tree | ||
23 | +case_conversion (tree type, tree value) | ||
24 | +{ | ||
25 | + if (value == NULL_TREE) | ||
26 | + return value; | ||
27 | + | ||
28 | + if (cxx_dialect >= cxx0x | ||
29 | + && (SCOPED_ENUM_P (type) | ||
30 | + || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value)))) | ||
31 | + { | ||
32 | + if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) | ||
33 | + type = type_promotes_to (type); | ||
34 | + value = perform_implicit_conversion (type, value, tf_warning_or_error); | ||
35 | + } | ||
36 | + return cxx_constant_value (value); | ||
37 | +} | ||
38 | + | ||
39 | /* Note that we've seen a definition of a case label, and complain if this | ||
40 | is a bad place for one. */ | ||
41 | |||
42 | @@ -2928,6 +2950,7 @@ finish_case_label (location_t loc, tree low_value, tree high_value) | ||
43 | { | ||
44 | tree cond, r; | ||
45 | struct cp_binding_level *p; | ||
46 | + tree type; | ||
47 | |||
48 | if (processing_template_decl) | ||
49 | { | ||
50 | @@ -2947,13 +2970,12 @@ finish_case_label (location_t loc, tree low_value, tree high_value) | ||
51 | if (!check_switch_goto (switch_stack->level)) | ||
52 | return error_mark_node; | ||
53 | |||
54 | - if (low_value) | ||
55 | - low_value = cxx_constant_value (low_value); | ||
56 | - if (high_value) | ||
57 | - high_value = cxx_constant_value (high_value); | ||
58 | + type = SWITCH_STMT_TYPE (switch_stack->switch_stmt); | ||
59 | + | ||
60 | + low_value = case_conversion (type, low_value); | ||
61 | + high_value = case_conversion (type, high_value); | ||
62 | |||
63 | - r = c_add_case_label (loc, switch_stack->cases, cond, | ||
64 | - SWITCH_STMT_TYPE (switch_stack->switch_stmt), | ||
65 | + r = c_add_case_label (loc, switch_stack->cases, cond, type, | ||
66 | low_value, high_value); | ||
67 | |||
68 | /* After labels, make any new cleanups in the function go into their | ||
69 | new file mode 100644 | ||
70 | index 0000000..55cf2ad | ||
71 | --- /dev/null | ||
72 | +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-switch2.C | ||
73 | @@ -0,0 +1,23 @@ | ||
74 | +// Test for constexpr conversion in case context | ||
75 | +// { dg-options -std=c++0x } | ||
76 | + | ||
77 | +enum class E { e1, e2 }; | ||
78 | + | ||
79 | +struct A | ||
80 | +{ | ||
81 | + E e; | ||
82 | + constexpr operator E() { return e; } | ||
83 | + constexpr A(E e): e(e) { } | ||
84 | +}; | ||
85 | + | ||
86 | +E e; | ||
87 | + | ||
88 | +int main() | ||
89 | +{ | ||
90 | + switch (e) | ||
91 | + { | ||
92 | + case A(E::e1): | ||
93 | + case A(E::e2): | ||
94 | + ; | ||
95 | + } | ||
96 | +} | ||
97 | diff --git a/gcc/testsuite/g++.dg/cpp0x/enum15.C b/gcc/testsuite/g++.dg/cpp0x/enum15.C | ||
98 | new file mode 100644 | ||
99 | index 0000000..d653216 | ||
100 | --- /dev/null | ||
101 | +++ b/gcc/testsuite/g++.dg/cpp0x/enum15.C | ||
102 | @@ -0,0 +1,20 @@ | ||
103 | +// PR c++/44311 | ||
104 | +// { dg-options -std=c++0x } | ||
105 | + | ||
106 | +enum class A { Val0, Val1 }; | ||
107 | + | ||
108 | +void foo (A a, int i) | ||
109 | +{ | ||
110 | + switch (a) | ||
111 | + { | ||
112 | + case A::Val0: break; | ||
113 | + case 1: break; // { dg-error "" } | ||
114 | + } | ||
115 | + | ||
116 | + switch (i) | ||
117 | + { | ||
118 | + case A::Val0: break; // { dg-error "" } | ||
119 | + case 1: break; | ||
120 | + case 2.0: break; | ||
121 | + } | ||
122 | +} | ||
123 | -- | ||
124 | 1.7.0.4 | ||
125 | |||