d: Use CONSTRUCTOR_ZERO_PADDING_BITS in the D FE [PR117832]

Adds a new wrapper function for `build_constructor', and calls it
instead to ensure that all CONSTRUCTOR nodes explicitly created by the
front-end have CONSTRUCTOR_ZERO_PADDING_BITS set.

Some places may not be necessary as it's guaranteed for there to be no
padding in the type, such as D dynamic arrays.  Other places this gets
turned into a double-memset when optimizations are turned off, as the
front-end already generates a memset call to zero out all padding on
initializing a variable.  The optimizer sees through this so will
correctly clear all bits once, so this can be improved later as-needed.

	PR d/117832

gcc/d/ChangeLog:

	* d-tree.h (build_padded_constructor): New prototype.
	* d-codegen.cc (build_padded_constructor): New function.
	(d_array_value): Call it.
	(build_memset_call): Likewise.
	(build_struct_literal): Likewise.
	(underlying_complex_expr): Likewise.
	(build_array_from_val): Likewise.
	(build_array_from_exprs): Likewise.
	(d_build_call): Likewise.
	(get_frame_for_symbol): Likewise.
	* d-convert.cc (convert_for_rvalue): Likewise.
	(convert_for_assignment): Likewise.
	* decl.cc (class DeclVisitor): Likewise.
	* expr.cc (class ExprVisitor): Likewise.
	* modules.cc (layout_moduleinfo): Likewise.
	* typeinfo.cc (class TypeInfoVisitor): Likewise.
This commit is contained in:
Iain Buclaw 2025-04-09 14:49:14 +02:00
parent 24d1832e0d
commit 3e3b665cc7
7 changed files with 45 additions and 28 deletions

View file

@ -317,7 +317,7 @@ d_array_value (tree type, tree len, tree data)
CONSTRUCTOR_APPEND_ELT (ce, len_field, len);
CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);
return build_constructor (type, ce);
return build_padded_constructor (type, ce);
}
/* Returns value representing the array length of expression EXP.
@ -898,7 +898,10 @@ build_memset_call (tree ptr, tree num)
{
tree cst = build_zero_cst (valtype);
if (TREE_CODE (cst) == CONSTRUCTOR)
return build_memcpy_call (ptr, build_address (cst), num);
{
CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1;
return build_memcpy_call (ptr, build_address (cst), num);
}
return modify_expr (build_deref (ptr), cst);
}
@ -1205,7 +1208,7 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
{
/* If the initializer was empty, use default zero initialization. */
if (vec_safe_is_empty (init))
return build_constructor (type, NULL);
return build_padded_constructor (type, NULL);
/* Struct literals can be seen for special enums representing `_Complex',
make sure to reinterpret the literal as the correct type. */
@ -1306,7 +1309,7 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
/* Ensure that we have consumed all values. */
gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
tree ctor = build_constructor (type, ve);
tree ctor = build_padded_constructor (type, ve);
if (constant_p)
TREE_CONSTANT (ctor) = 1;
@ -1314,6 +1317,17 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
return ctor;
}
/* Return a new zero padded CONSTRUCTOR node whose type is TYPE and values are
in the vec pointed to by VALS. */
tree
build_padded_constructor (tree type, vec<constructor_elt, va_gc> *vals)
{
tree ctor = build_constructor (type, vals);
CONSTRUCTOR_ZERO_PADDING_BITS (ctor) = 1;
return ctor;
}
/* Given the TYPE of an anonymous field inside T, return the
FIELD_DECL for the field. If not found return NULL_TREE.
Because anonymous types can nest, we must also search all
@ -1647,7 +1661,7 @@ underlying_complex_expr (tree type, tree expr)
real_part (expr));
CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)),
imaginary_part (expr));
return build_constructor (type, ve);
return build_padded_constructor (type, ve);
}
/* Replace type in the reinterpret cast with a cast to the record type. */
@ -1852,7 +1866,7 @@ build_array_from_val (Type *type, tree val)
for (size_t i = 0; i < dims; i++)
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
return build_constructor (build_ctype (type), elms);
return build_padded_constructor (build_ctype (type), elms);
}
/* Build a static array of type TYPE from an array of EXPS.
@ -1886,7 +1900,7 @@ build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
init = build_memset_call (var);
/* Initialize the temporary. */
tree assign = modify_expr (var, build_constructor (satype, elms));
tree assign = modify_expr (var, build_padded_constructor (satype, elms));
return compound_expr (compound_expr (init, assign), var);
}
@ -2301,7 +2315,7 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
&& TREE_CODE (targ) != CONSTRUCTOR)
{
tree t = build_constructor (TREE_TYPE (targ), NULL);
tree t = build_padded_constructor (TREE_TYPE (targ), NULL);
targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
}
@ -2613,7 +2627,7 @@ get_frame_for_symbol (Dsymbol *sym)
framefields = DECL_CHAIN (framefields);
}
frame_ref = build_address (build_constructor (type, ve));
frame_ref = build_address (build_padded_constructor (type, ve));
}
}

View file

@ -688,7 +688,7 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
CONSTRUCTOR_APPEND_ELT (elms, index, value);
}
return build_constructor (build_ctype (totype), elms);
return build_padded_constructor (build_ctype (totype), elms);
}
}
@ -788,7 +788,7 @@ convert_for_assignment (Expression *expr, Type *totype, bool literalp)
TypeSArray *sa_type = tbtype->isTypeSArray ();
uinteger_t count = sa_type->dim->toUInteger ();
tree ctor = build_constructor (build_ctype (totype), NULL);
tree ctor = build_padded_constructor (build_ctype (totype), NULL);
if (count)
{
vec <constructor_elt, va_gc> *ce = NULL;

View file

@ -575,6 +575,7 @@ extern tree build_struct_comparison (tree_code, StructDeclaration *,
extern tree build_array_struct_comparison (tree_code, StructDeclaration *,
tree, tree, tree);
extern tree build_struct_literal (tree, vec <constructor_elt, va_gc> *);
extern tree build_padded_constructor (tree, vec <constructor_elt, va_gc> *);
extern tree component_ref (tree, tree);
extern tree build_assign (tree_code, tree, tree);
extern tree modify_expr (tree, tree);

View file

@ -651,7 +651,7 @@ public:
}
DECL_INITIAL (vtblsym->csym)
= build_constructor (TREE_TYPE (vtblsym->csym), elms);
= build_padded_constructor (TREE_TYPE (vtblsym->csym), elms);
d_finish_decl (vtblsym->csym);
d->semanticRun (PASS::obj);

View file

@ -2457,7 +2457,7 @@ public:
CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
result = build_nop (build_ctype (e->type),
build_constructor (aatype, ce));
build_padded_constructor (aatype, ce));
}
else
gcc_unreachable ();
@ -2530,7 +2530,7 @@ public:
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
}
tree ctor = build_constructor (type, elms);
tree ctor = build_padded_constructor (type, elms);
TREE_CONSTANT (ctor) = 1;
this->result_ = ctor;
return;
@ -2612,8 +2612,10 @@ public:
this->result_ = d_array_value (build_ctype (e->type),
size_int (0), null_pointer_node);
else
this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
NULL);
{
tree arrtype = make_array_type (tb->nextOf (), 0);
this->result_ = build_padded_constructor (arrtype, NULL);
}
return;
}
@ -2654,7 +2656,7 @@ public:
/* Now return the constructor as the correct type. For static arrays there
is nothing else to do. For dynamic arrays, return a two field struct.
For pointers, return the address. */
tree ctor = build_constructor (satype, elms);
tree ctor = build_padded_constructor (satype, elms);
tree type = build_ctype (e->type);
/* Nothing else to do for static arrays. */
@ -2755,7 +2757,7 @@ public:
TypeAArray *ta = tb->isTypeAArray ();
if (e->keys->length == 0)
{
this->result_ = build_constructor (build_ctype (ta), NULL);
this->result_ = build_padded_constructor (build_ctype (ta), NULL);
return;
}
@ -2787,7 +2789,7 @@ public:
CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
tree result = build_nop (build_ctype (e->type),
build_constructor (aatype, ce));
build_padded_constructor (aatype, ce));
this->result_ = compound_expr (init, result);
}
@ -2798,7 +2800,7 @@ public:
/* Handle empty struct literals. */
if (e->elements == NULL || e->sd->fields.length == 0)
{
this->result_ = build_constructor (build_ctype (e->type), NULL);
this->result_ = build_padded_constructor (build_ctype (e->type), NULL);
return;
}
@ -2849,7 +2851,7 @@ public:
elem = d_save_expr (elem);
if (initializer_zerop (elem))
value = build_constructor (build_ctype (ftype), NULL);
value = build_padded_constructor (build_ctype (ftype), NULL);
else
value = build_array_from_val (ftype, elem);
}
@ -2948,7 +2950,7 @@ public:
if (constant_p)
this->result_ = build_vector_from_ctor (type, elms);
else
this->result_ = build_constructor (type, elms);
this->result_ = build_padded_constructor (type, elms);
}
else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
{

View file

@ -667,7 +667,7 @@ layout_moduleinfo (Module *decl)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
build_constructor (satype, elms));
build_padded_constructor (satype, elms));
}
if (flags & MIlocalClasses)
@ -684,7 +684,7 @@ layout_moduleinfo (Module *decl)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.length));
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
build_constructor (satype, elms));
build_padded_constructor (satype, elms));
}
if (flags & MIname)

View file

@ -489,14 +489,14 @@ class TypeInfoVisitor : public Visitor
CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));
/* Add to the array of interfaces. */
value = build_constructor (vtbl_interface_type_node, v);
value = build_padded_constructor (vtbl_interface_type_node, v);
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
}
tree domain = size_int (cd->vtblInterfaces->length - 1);
tree arrtype = build_array_type (vtbl_interface_type_node,
build_index_type (domain));
return build_constructor (arrtype, elms);
return build_padded_constructor (arrtype, elms);
}
/* Write out the interfacing vtable[] of base class BCD that will be accessed
@ -542,7 +542,7 @@ class TypeInfoVisitor : public Visitor
tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
tree value = build_constructor (vtbltype, elms);
tree value = build_padded_constructor (vtbltype, elms);
this->layout_field (value);
}
@ -1160,7 +1160,7 @@ public:
CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
build_typeinfo (d->loc, arg->type));
}
tree ctor = build_constructor (build_ctype (satype), elms);
tree ctor = build_padded_constructor (build_ctype (satype), elms);
tree decl = this->internal_reference (ctor);
tree length = size_int (ti->arguments->length);