This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/37146] [4.4 Regression] Invalid types with COND_EXPR
- From: "jakub at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 1 Sep 2008 12:40:08 -0000
- Subject: [Bug c++/37146] [4.4 Regression] Invalid types with COND_EXPR
- References: <bug-37146-12710@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #3 from jakub at gcc dot gnu dot org 2008-09-01 12:40 -------
This is a C++ FE bug. Shorter testcase:
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;
}
The bug is IMHO in build_conditional_expr. One of:
arg2_type = unlowered_expr_type (arg2);
arg3_type = unlowered_expr_type (arg3);
calls returns a different type from TREE_TYPE (argX), as that's bitfield
COMPONENT_REF. Neither of the types are void and neither is class type, so
nothing is converted first and we reach:
/* [expr.cond]
If the second and third operands are lvalues and have the same
type, the result is of that type and is an lvalue. */
if (real_lvalue_p (arg2)
&& real_lvalue_p (arg3)
&& same_type_p (arg2_type, arg3_type))
{
result_type = arg2_type;
goto valid_operands;
}
where arg2_type is the same as arg3_type, but TREE_TYPE (arg2) != TREE_TYPE
(arg3), not even useless type conversion, and at valid_operands we build it
right away as COND_EXPR. Can x ? bitfield : val be even considered as valid
lvalue by C++ standard (I mean e.g. bitfield can have different number of bits
from val)? If we don't shortcut here, force_rvalue is called on both arguments
and that will call the needed convert_bitfield_to_declared_type somewhere.
E.g.:
--- call.c.jj2008-08-29 18:23:10.000000000 +0200
+++ call.c2008-09-01 14:27:24.000000000 +0200
@@ -3596,7 +3596,9 @@ build_conditional_expr (tree arg1, tree
type, the result is of that type and is an lvalue. */
if (real_lvalue_p (arg2)
&& real_lvalue_p (arg3)
- && same_type_p (arg2_type, arg3_type))
+ && same_type_p (arg2_type, arg3_type)
+ && is_bitfield_expr_with_lowered_type (arg2) == NULL_TREE
+ && is_bitfield_expr_with_lowered_type (arg3) == NULL_TREE)
{
result_type = arg2_type;
goto valid_operands;
cures this testcase, but I'm not sure if it is correct from C++ standard POV.
--
jakub at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jason at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37146