From 7508a7e958ea06eb311a4a106312634eaf6d40c3 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sat, 18 Jul 2020 17:14:54 +0200 Subject: d: Fix associative array literals that don't have alignment holes filled Associative array literal keys with alignment holes are now filled using memset() prior to usage, with LTR evaluation of side-effects enforced. gcc/d/ChangeLog: PR d/96152 * d-codegen.cc (build_array_from_exprs): New function. * d-tree.h (build_array_from_exprs): Declare. * expr.cc (ExprVisitor::visit (AssocArrayLiteralExp *)): Use build_array_from_exprs to generate key and value arrays. gcc/testsuite/ChangeLog: PR d/96152 * gdc.dg/pr96152.d: New test. --- gcc/d/d-codegen.cc | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'gcc/d/d-codegen.cc') diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index a38aa6c..2dce09d 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -1722,6 +1722,42 @@ build_array_from_val (Type *type, tree val) return build_constructor (build_ctype (type), elms); } +/* Build a static array of type TYPE from an array of EXPS. + If CONST_P is true, then all elements in EXPS are constants. */ + +tree +build_array_from_exprs (Type *type, Expressions *exps, bool const_p) +{ + /* Build a CONSTRUCTOR from all expressions. */ + vec *elms = NULL; + vec_safe_reserve (elms, exps->length); + + Type *etype = type->nextOf (); + tree satype = make_array_type (etype, exps->length); + + for (size_t i = 0; i < exps->length; i++) + { + Expression *expr = (*exps)[i]; + tree t = build_expr (expr, const_p); + CONSTRUCTOR_APPEND_ELT (elms, size_int (i), + convert_expr (t, expr->type, etype)); + } + + /* 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_constructor (satype, elms)); + return compound_expr (compound_expr (init, assign), var); +} + + /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */ tree -- cgit v1.1