diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index 51f0985f1..0a6860ce1 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -8,6 +8,10 @@ (d_init_builtins): Build va_list type for D frontend. * d-lang.cc(d_init): Use isLP64 to determine LP64 targets. (d_add_builtin_version): Set is64bit if target is X86_64. + * d-codegen.cc(convert_for_assignment): Use memset to implement front + end code (struct = 0) here, rather than build an empty constructor. + * d-elem.cc(AssignExp::toElem): Remove handling of (struct = 0) and + call convert_for_assignment. 2013-05-28 Iain Buclaw diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index bcb56a9ca..e8c375bd3 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -564,20 +564,23 @@ convert_for_assignment (tree expr, Type *exp_type, Type *target_type) } } - if (!target_type->isscalar() && ebtype->isintegral()) + if (tbtype->ty == Tstruct && ebtype->isintegral()) { - // D Front end uses IntegerExp (0) to mean zero-init a structure - // This could go in convert for assignment, but we only see this for - // internal init code -- this also includes default init for _d_newarrayi... + // D Front end uses IntegerExp (0) to mean zero-init a structure. + // Use memset to fill struct. if (integer_zerop (expr)) { - tree empty = build_constructor (target_type->toCtype(), NULL); - TREE_CONSTANT (empty) = 1; - TREE_STATIC (empty) = 1; - return empty; - } + StructDeclaration *sd = ((TypeStruct *) tbtype)->sym; + tree var = build_local_var (target_type->toCtype()); - gcc_unreachable(); + tree init = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMSET), 3, + build_address (var), expr, + size_int (sd->structsize)); + + return compound_expr (init, var); + } + else + gcc_unreachable(); } return convert_expr (expr, exp_type, target_type); diff --git a/gcc/d/d-elem.cc b/gcc/d/d-elem.cc index 1218696b7..77619530c 100644 --- a/gcc/d/d-elem.cc +++ b/gcc/d/d-elem.cc @@ -935,46 +935,36 @@ AssignExp::toElem (IRState *irs) if (op == TOKconstruct) { tree lhs = e1->toElem (irs); + tree rhs = convert_for_assignment (e2->toElem (irs), e2->type, e1->type); Type *tb1 = e1->type->toBasetype(); - tree result = NULL_TREE; + + if (e1->op == TOKvar) + { + Declaration *decl = ((VarExp *) e1)->var; + // Look for reference initializations + if (decl->storage_class & (STCout | STCref)) + { + // Want reference to lhs, not indirect ref. + lhs = TREE_OPERAND (lhs, 0); + rhs = build_address (rhs); + } + } + + tree result = modify_expr (type->toCtype(), lhs, rhs); if (tb1->ty == Tstruct && e2->op == TOKint64) { + // Maybe set-up hidden pointer to outer scope context. StructDeclaration *sd = ((TypeStruct *) tb1)->sym; - // D Front end uses IntegerExp (0) to mean zero-init a structure. - // Use memset to fill struct. - result = d_build_call_nary (builtin_decl_explicit (BUILT_IN_MEMSET), 3, - build_address (lhs), size_zero_node, - size_int (sd->structsize)); - - - // Maybe set-up hidden pointer to outer scope context. if (sd->isNested()) { tree vthis_field = sd->vthis->toSymbol()->Stree; tree vthis_value = irs->getVThis (sd, this); tree vthis_exp = modify_expr (component_ref (lhs, vthis_field), vthis_value); - result = maybe_compound_expr (result, vthis_exp); - } - } - else - { - tree rhs = convert_for_assignment (e2->toElem (irs), e2->type, e1->type); - - if (e1->op == TOKvar) - { - Declaration *decl = ((VarExp *) e1)->var; - // Look for reference initializations - if (decl->storage_class & (STCout | STCref)) - { - // Want reference to lhs, not indirect ref. - lhs = TREE_OPERAND (lhs, 0); - rhs = build_address (rhs); - } + result = compound_expr (result, vthis_exp); } - result = modify_expr (type->toCtype(), lhs, rhs); } return result;