d: Fix segfault in build_frontend_type on alpha-*-*
authorIain Buclaw <ibuclaw@gdcproject.org>
Mon, 1 Jun 2020 11:27:06 +0000 (13:27 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Tue, 2 Jun 2020 07:33:51 +0000 (09:33 +0200)
The va_list type for Alpha includes a nameless dummy field for alignment
purposes.  To transpose this into D, a field named "__pad%d" is inserted
into the struct definition.

It was also noticed that in the D front-end AST copy of the backend
type, all offsets for fields generated by build_frontend_type were set
to zero due to a wrong assumption that DECL_FIELD_OFFSET would have a
non-zero value.  This has been fixed to use byte_position instead.

gcc/d/ChangeLog:

* d-builtins.cc (build_frontend_type): Handle struct fields with NULL
DECL_NAME.  Use byte_position to get the real field offset.

gcc/d/d-builtins.cc

index a5654a66bf5741db9947e9b8c36e87405caa44f9..1cb5407f8a9b1052b8c2b7d53a23b3948a2b62b3 100644 (file)
@@ -238,6 +238,9 @@ build_frontend_type (tree type)
       sdecl->type->ctype = type;
       sdecl->type->merge2 ();
 
+      /* Add both named and anonymous fields as members of the struct.
+        Anonymous fields still need a name in D, so call them "__pad%d".  */
+      int anonfield_id = 0;
       sdecl->members = new Dsymbols;
 
       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
@@ -249,12 +252,19 @@ build_frontend_type (tree type)
              return NULL;
            }
 
-         Identifier *fident
-           = Identifier::idPool (IDENTIFIER_POINTER (DECL_NAME (field)));
+         Identifier *fident;
+         if (DECL_NAME (field) == NULL_TREE)
+           fident = Identifier::generateId ("__pad", anonfield_id++);
+         else
+           {
+             const char *name = IDENTIFIER_POINTER (DECL_NAME (field));
+             fident = Identifier::idPool (name);
+           }
+
          VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
                                                       NULL);
          vd->parent = sdecl;
-         vd->offset = tree_to_uhwi (DECL_FIELD_OFFSET (field));
+         vd->offset = tree_to_uhwi (byte_position (field));
          vd->semanticRun = PASSsemanticdone;
          vd->csym = field;
          sdecl->members->push (vd);