https://gcc.gnu.org/g:3e3b665cc77791f2e088aeee124d8a9fb7f6eb41

commit r15-9333-g3e3b665cc77791f2e088aeee124d8a9fb7f6eb41
Author: Iain Buclaw <ibuc...@gdcproject.org>
Date:   Wed Apr 9 14:49:14 2025 +0200

    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.

Diff:
---
 gcc/d/d-codegen.cc | 32 +++++++++++++++++++++++---------
 gcc/d/d-convert.cc |  4 ++--
 gcc/d/d-tree.h     |  1 +
 gcc/d/decl.cc      |  2 +-
 gcc/d/expr.cc      | 22 ++++++++++++----------
 gcc/d/modules.cc   |  4 ++--
 gcc/d/typeinfo.cc  |  8 ++++----
 7 files changed, 45 insertions(+), 28 deletions(-)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index ad71486e3ba8..1a7575aac22c 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -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));
            }
        }
 
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 4b195841c493..c5b0d653e877 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -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;
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 42d01e455950..ebbbe715daca 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -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);
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 250d148e56f4..136f78b32ff0 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -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);
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 46e651457911..1c1ecf2c6db3 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -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)
       {
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 471ac43cbead..813d94bc5c4e 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -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)
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index e81b2f0157fa..4c3e9e40b489 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -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);

Reply via email to