re PR c++/37146 (Invalid types with COND_EXPR)

PR c++/37146
	* cp-gimplify.c (cp_genericize_r): Fix up bitfield operands of
	COND_EXPR.

	* g++.dg/torture/pr37146-1.C: New test.
	* g++.dg/torture/pr37146-2.C: New test.
	* g++.dg/expr/bitfield10.C: New test.

From-SVN: r141045
This commit is contained in:
Jakub Jelinek 2008-10-10 20:22:17 +02:00 committed by Jakub Jelinek
parent e14165f41a
commit bbdf56821d
6 changed files with 207 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2008-10-10 Jakub Jelinek <jakub@redhat.com>
PR c++/37146
* cp-gimplify.c (cp_genericize_r): Fix up bitfield operands of
COND_EXPR.
2008-10-09 Jakub Jelinek <jakub@redhat.com>
PR c++/37568

View File

@ -803,6 +803,34 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
CLEANUP_BODY (stmt),
CLEANUP_EXPR (stmt));
/* COND_EXPR might have incompatible types in branches if one or both
arms are bitfields. Fix it up now. */
else if (TREE_CODE (stmt) == COND_EXPR)
{
tree type_left
= (TREE_OPERAND (stmt, 1)
? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
: NULL_TREE);
tree type_right
= (TREE_OPERAND (stmt, 2)
? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
: NULL_TREE);
if (type_left)
{
TREE_OPERAND (stmt, 1)
= fold_convert (type_left, TREE_OPERAND (stmt, 1));
gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
type_left));
}
if (type_right)
{
TREE_OPERAND (stmt, 2)
= fold_convert (type_right, TREE_OPERAND (stmt, 2));
gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
type_right));
}
}
pointer_set_insert (p_set, *stmt_p);
return NULL;

View File

@ -1,3 +1,10 @@
2008-10-10 Jakub Jelinek <jakub@redhat.com>
PR c++/37146
* g++.dg/torture/pr37146-1.C: New test.
* g++.dg/torture/pr37146-2.C: New test.
* g++.dg/expr/bitfield10.C: New test.
2008-10-08 Jerry DeLisle <jvdelisle@gcc.gnu.org
PR libfortran/37707

View File

@ -0,0 +1,16 @@
// 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;
}

View File

@ -0,0 +1,83 @@
// PR c++/37146
// { dg-do run }
extern "C" void abort ();
int a, b;
struct A { int i:8; int j:8; int k:16; int l:32; } c;
void
f1 (int x, int y)
{
(x ? a : b) = y;
}
void
f2 (int x, int y)
{
(x ? c.i : c.j) = y;
}
void
f3 (int x, int y)
{
(x ? c.i : a) = y;
}
void
f4 (int x, int y)
{
(x ? c.i : c.k) = y;
}
void
f5 (int x, int y)
{
(x ? c.l : b) = y;
}
#define CHECK(var, exp) \
do \
{ \
if (var != exp) \
abort (); \
var = -1; \
if (a != -1 \
|| b != -1 \
|| c.i != -1 \
|| c.j != -1 \
|| c.k != -1 \
|| c.l != -1) \
abort (); \
} \
while (0)
int
main ()
{
a = -1;
b = -1;
c.i = -1;
c.j = -1;
c.k = -1;
c.l = -1;
f1 (1, 264);
CHECK (a, 264);
f1 (0, 264);
CHECK (b, 264);
f2 (1, 112);
CHECK (c.i, 112);
f2 (0, 112);
CHECK (c.j, 112);
f3 (1, 26);
CHECK (c.i, 26);
f3 (0, 26);
CHECK (a, 26);
f4 (1, 107);
CHECK (c.i, 107);
f4 (0, 107);
CHECK (c.k, 107);
f5 (1, 95);
CHECK (c.l, 95);
f5 (0, 95);
CHECK (b, 95);
}

View File

@ -0,0 +1,67 @@
// PR c++/37146
// { dg-do run }
extern "C" void abort ();
int a, b;
struct A { int i:8; int j:8; int k:16; int l:32; } c;
int
f1 (int x)
{
return x ? a : b;
}
int
f2 (int x)
{
return x ? c.i : c.j;
}
int
f3 (int x)
{
return x ? c.i : a;
}
int
f4 (int x)
{
return x ? c.i : c.k;
}
int
f5 (int x)
{
return x ? c.l : b;
}
int
main ()
{
a = 17;
b = 18;
c.i = 19;
c.j = 20;
c.k = 21;
c.l = 22;
if (f1 (1) != a)
abort ();
if (f1 (0) != b)
abort ();
if (f2 (1) != c.i)
abort ();
if (f2 (0) != c.j)
abort ();
if (f3 (1) != c.i)
abort ();
if (f3 (0) != a)
abort ();
if (f4 (1) != c.i)
abort ();
if (f4 (0) != c.k)
abort ();
if (f5 (1) != c.l)
abort ();
if (f5 (0) != b)
abort ();
}