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:
parent
e14165f41a
commit
bbdf56821d
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
16
gcc/testsuite/g++.dg/expr/bitfield10.C
Normal file
16
gcc/testsuite/g++.dg/expr/bitfield10.C
Normal 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;
|
||||
}
|
83
gcc/testsuite/g++.dg/torture/pr37146-1.C
Normal file
83
gcc/testsuite/g++.dg/torture/pr37146-1.C
Normal 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);
|
||||
}
|
67
gcc/testsuite/g++.dg/torture/pr37146-2.C
Normal file
67
gcc/testsuite/g++.dg/torture/pr37146-2.C
Normal 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 ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user