summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0342-PR-c-44311.patch
diff options
context:
space:
mode:
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.patch125
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 @@
1From f6945c41cc9a66590ea92a1d0d7c862d14ccd23c Mon Sep 17 00:00:00 2001
2From: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Wed, 25 May 2011 20:30:21 +0000
4Subject: [PATCH] PR c++/44311
5 * decl.c (case_conversion): New.
6 (finish_case_label): Use it.
7
8git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174237 138bc75d-0d04-0410-961f-82ee72b054a4
9
10index 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
69new file mode 100644
70index 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+}
97diff --git a/gcc/testsuite/g++.dg/cpp0x/enum15.C b/gcc/testsuite/g++.dg/cpp0x/enum15.C
98new file mode 100644
99index 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--
1241.7.0.4
125