diff options
Diffstat (limited to 'gcc/d/d-codegen.cc')
-rw-r--r-- | gcc/d/d-codegen.cc | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 1a7575a..e35f75a 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -717,10 +717,11 @@ build_address (tree exp) if (AGGREGATE_TYPE_P (TREE_TYPE (exp)) && !aggregate_value_p (TREE_TYPE (exp), exp)) { - tree tmp = build_local_temp (TREE_TYPE (exp)); - init = compound_expr (init, build_memset_call (tmp)); - init = compound_expr (init, modify_expr (tmp, exp)); - exp = tmp; + tree target = force_target_expr (exp); + tree ptr = build_address (TARGET_EXPR_SLOT (target)); + init = compound_expr (init, target); + init = compound_expr (init, build_clear_padding_call (ptr)); + exp = TARGET_EXPR_SLOT (target); } else exp = force_target_expr (exp); @@ -891,17 +892,13 @@ build_memset_call (tree ptr, tree num) } /* Use a zero constant to fill the destination if setting the entire object. - For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment, - which can then be merged with other stores to the object. */ + For CONSTRUCTORs, also set CONSTRUCTOR_ZERO_PADDING_BITS. */ tree valtype = TREE_TYPE (TREE_TYPE (ptr)); if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num)) { tree cst = build_zero_cst (valtype); if (TREE_CODE (cst) == CONSTRUCTOR) - { - CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1; - return build_memcpy_call (ptr, build_address (cst), num); - } + CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1; return modify_expr (build_deref (ptr), cst); } @@ -910,6 +907,18 @@ build_memset_call (tree ptr, tree num) ptr, integer_zero_node, num); } +/* Build a call to built-in clear_padding(), clears padding bits inside of the + object representation of object pointed by PTR. */ + +tree +build_clear_padding_call (tree ptr) +{ + gcc_assert (POINTER_TYPE_P (TREE_TYPE (ptr))); + + return build_call_expr (builtin_decl_explicit (BUILT_IN_CLEAR_PADDING), 1, + ptr); +} + /* Return TRUE if the struct SD is suitable for comparison using memcmp. This is because we don't guarantee that padding is zero-initialized for a stack variable, so we can't use memcmp to compare struct values. */ @@ -1893,15 +1902,13 @@ build_array_from_exprs (Type *type, Expressions *exps, bool const_p) /* Create a new temporary to store the array. */ tree var = build_local_temp (satype); - /* Fill any alignment holes with zeroes. */ - TypeStruct *ts = etype->baseElemOf ()->isTypeStruct (); - tree init = NULL; - if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ())) - init = build_memset_call (var); - /* Initialize the temporary. */ tree assign = modify_expr (var, build_padded_constructor (satype, elms)); - return compound_expr (compound_expr (init, assign), var); + + /* Fill any alignment holes with zeroes. */ + tree clear_padding = build_clear_padding_call (build_address (var)); + + return compound_expr (compound_expr (assign, clear_padding), var); } |