This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] c++/37146
- From: Dodji Seketeli <dodji at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>, Jason Merrill <jason at redhat dot com>
- Cc: Gcc Patch List <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>
- Date: Mon, 15 Sep 2008 17:34:09 +0200
- Subject: [PATCH] c++/37146
Hello,
This patch proposes a fix for PR37146. The last comments of the PR at
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37146 shed some light on the
final choice of the patch.
It has been regtested on x86_64 in trunk.
Would it be okay to commit ?
Thanks,
Dodji.
b/gcc/cp/ChangeLog:
2008-09-13 Dodji Seketeli <dodji@redhat.com>
PR c++/37146
*call.c (build_conditional_expr): When the arguments of the
conditional expression are bit-fields, do not only consider
the declared type said bit-field.
gcc/testsuite/ChangeLog:
2008-09-13 Dodji Seketeli <dodji@redhat.com>
PR c++/37146
* g++.dg/expr/expr-cond.C: New test.
* g++.dg/expr/expr-cond-2.C: New test.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 653e06e..f67162d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3436,8 +3436,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
array-to-pointer (_conv.array_), and function-to-pointer
(_conv.func_) standard conversions are performed on the second
and third operands. */
- arg2_type = unlowered_expr_type (arg2);
- arg3_type = unlowered_expr_type (arg3);
+ arg2_type = TREE_TYPE (arg2);
+ arg3_type = TREE_TYPE (arg3);
if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
{
/* Do the conversions. We don't these for `void' type arguments
diff --git a/gcc/testsuite/g++.dg/expr/expr-cond-2.C b/gcc/testsuite/g++.dg/expr/expr-cond-2.C
new file mode 100644
index 0000000..bd6ea0d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/expr-cond-2.C
@@ -0,0 +1,18 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR c++/37146
+//
+// { dg-do compile }
+
+enum E { E0 = 0, E1 = 'E' };
+
+struct S
+{
+ E s0 : 8;
+ enum E foo (bool, E);
+};
+
+E S::foo (bool a, E b)
+{
+ return a ? s0 : b;
+}
+
diff --git a/gcc/testsuite/g++.dg/expr/expr-cond.C b/gcc/testsuite/g++.dg/expr/expr-cond.C
new file mode 100644
index 0000000..4108fbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/expr-cond.C
@@ -0,0 +1,35 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR c++/37146
+//
+// { dg-do compile }
+
+enum E { E0 = 0, E1 = 'E' };
+
+struct S
+{
+ E s0 : 8;
+ enum E foo (bool, E);
+};
+
+E S::foo (bool t, E e)
+{
+ return t ? s0 : e;
+}
+
+int a;
+int b;
+struct A { int i:8; int j:8; int k:16; int l:32; } c;
+
+void
+foo (int x, int y)
+{
+ (x ? a : b) = y;
+ (x ? c.i : c.j) = y;
+ (x ? c.i : a) = y; // { dg-error "lvalue required as left operand" }
+ (x ? c.i : c.k) = y; // { dg-error "lvalue required as left operand" }
+#if __INT_MAX__ == 2147483647
+ (x ? c.l : b) = y;
+#endif
+}
+
+