diff options
Diffstat (limited to 'gcc/d/d-convert.cc')
-rw-r--r-- | gcc/d/d-convert.cc | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc index ec5da6c..2023245 100644 --- a/gcc/d/d-convert.cc +++ b/gcc/d/d-convert.cc @@ -620,7 +620,7 @@ convert_expr (tree exp, Type *etype, Type *totype) return result ? result : convert (build_ctype (totype), exp); } -/* Return a TREE represenwation of EXPR, whose type has been converted from +/* Return a TREE representation of EXPR, whose type has been converted from * ETYPE to TOTYPE, and is being used in an rvalue context. */ tree @@ -635,20 +635,27 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype) { /* If casting from bool, the result is either 0 or 1, any other value violates @safe code, so enforce that it is never invalid. */ - if (CONSTANT_CLASS_P (expr)) - result = d_truthvalue_conversion (expr); - else + for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF; + ref = TREE_OPERAND (ref, 0)) { - /* Reinterpret the boolean as an integer and test the first bit. - The generated code should end up being equivalent to: + /* If the expression is a field that's part of a union, reinterpret + the boolean as an integer and test the first bit. The generated + code should end up being equivalent to: *cast(ubyte *)&expr & 1; */ - machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr)); - tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1); - result = fold_build2 (BIT_AND_EXPR, mtype, - build_vconvert (mtype, expr), - build_one_cst (mtype)); + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE) + { + machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr)); + tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1); + result = fold_build2 (BIT_AND_EXPR, mtype, + build_vconvert (mtype, expr), + build_one_cst (mtype)); + break; + } } + if (result == NULL_TREE) + result = d_truthvalue_conversion (expr); + result = convert (build_ctype (tbtype), result); } @@ -845,7 +852,7 @@ convert_for_condition (tree expr, Type *type) break; default: - result = expr; + result = convert_for_rvalue (expr, type, type); break; } |