d: Fix ICEs in the front-end when pointer size is 16-bit.
authorIain Buclaw <ibuclaw@gdcproject.org>
Mon, 31 Aug 2020 11:31:04 +0000 (13:31 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Mon, 31 Aug 2020 13:53:44 +0000 (15:53 +0200)
In the lowering of `bt*' intrinsics, some integer constants had
mismatched types, and bitsize was set to the wrong value.

In base_vtable_offset, the base offset value was calculated incorrectly.
The TypeInfo_Class object is comprised of 18 pointers and 1 uint field,
so now the internal classinfo type size is used instead.

gcc/d/ChangeLog:

* d-target.cc (Target::_init): Don't set classinfosize.
* d-tree.h (base_vtable_offset): Move under typeinfo.cc section.
* decl.cc (base_vtable_offset): Move to...
* typeinfo.cc (base_vtable_offset): ...here.  Get base offset from
internal TypeInfo_Class type.
* intrinsics.cc (expand_intrinsic_bt): Use pointer TYPE_SIZE for
setting bitsize value.  Build integer constants of correct type.

gcc/d/d-target.cc
gcc/d/d-tree.h
gcc/d/decl.cc
gcc/d/intrinsics.cc
gcc/d/typeinfo.cc

index 71156e34a9c2e4343837a7465972c1a96df4fe3f..ea425ad897c39c633c6d6025ba2b1267ea770b5b 100644 (file)
@@ -115,9 +115,6 @@ Target::_init (const Param &)
                   (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));
   this->realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);
 
-  /* Size of run-time TypeInfo object.  */
-  this->classinfosize = 19 * this->ptrsize;
-
   /* Much of the dmd front-end uses ints for sizes and offsets, and cannot
      handle any larger data type without some pervasive rework.  */
   this->maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (integer_type_node));
index b01a133fe62f18b79106ff8e082c078f578ddea2..31fe5181912e5f10a6f481f2d305eef8a3985ee9 100644 (file)
@@ -622,7 +622,6 @@ extern tree make_thunk (FuncDeclaration *, int);
 extern tree start_function (FuncDeclaration *);
 extern void finish_function (tree);
 extern void mark_needed (tree);
-extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
 extern tree get_vtable_decl (ClassDeclaration *);
 extern tree build_new_class_expr (ClassReferenceExp *);
 extern tree aggregate_initializer_decl (AggregateDeclaration *);
@@ -660,6 +659,7 @@ extern tree build_libcall (libcall_fn, Type *, int ...);
 extern bool have_typeinfo_p (ClassDeclaration *);
 extern tree layout_typeinfo (TypeInfoDeclaration *);
 extern tree layout_classinfo (ClassDeclaration *);
+extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
 extern tree get_typeinfo_decl (TypeInfoDeclaration *);
 extern tree get_classinfo_decl (ClassDeclaration *);
 extern tree build_typeinfo (const Loc &, Type *);
index 008a2bb16ab98215417502e219be30c49c7185cd..8e4237dd0561d3227378e25f79bebd640670cfcb 100644 (file)
@@ -1991,42 +1991,6 @@ mark_needed (tree decl)
     }
 }
 
-/* Get the offset to the BC's vtbl[] initializer from the start of CD.
-   Returns "~0u" if the base class is not found in any vtable interfaces.  */
-
-unsigned
-base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
-{
-  unsigned csymoffset = target.classinfosize;
-  unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
-  csymoffset += cd->vtblInterfaces->length * interfacesize;
-
-  for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
-    {
-      BaseClass *b = (*cd->vtblInterfaces)[i];
-      if (b == bc)
-       return csymoffset;
-      csymoffset += b->sym->vtbl.length * target.ptrsize;
-    }
-
-  /* Check all overriding interface vtbl[]s.  */
-  for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)
-    {
-      for (size_t k = 0; k < cd2->vtblInterfaces->length; k++)
-       {
-         BaseClass *bs = (*cd2->vtblInterfaces)[k];
-         if (bs->fillVtbl (cd, NULL, 0))
-           {
-             if (bc == bs)
-               return csymoffset;
-             csymoffset += bs->sym->vtbl.length * target.ptrsize;
-           }
-       }
-    }
-
-  return ~0u;
-}
-
 /* Get the VAR_DECL of the vtable symbol for DECL.  If this does not yet exist,
    create it.  The vtable is accessible via ClassInfo, but since it is needed
    frequently (like for rtti comparisons), make it directly accessible.  */
index 486db1277472f3e1ec560026eafddd03d559a9c0..1b12a3ec6fbd5945ae27e1a1b376cfa1fb6f00d2 100644 (file)
@@ -303,7 +303,7 @@ expand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)
   tree type = TREE_TYPE (TREE_TYPE (ptr));
 
   /* size_t bitsize = sizeof(*ptr) * BITS_PER_UNIT;  */
-  tree bitsize = fold_convert (type, TYPE_SIZE (type));
+  tree bitsize = fold_convert (type, TYPE_SIZE (TREE_TYPE (ptr)));
 
   /* ptr[bitnum / bitsize]  */
   ptr = build_array_index (ptr, fold_build2 (TRUNC_DIV_EXPR, type,
@@ -312,14 +312,15 @@ expand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)
 
   /* mask = 1 << (bitnum % bitsize);  */
   bitnum = fold_build2 (TRUNC_MOD_EXPR, type, bitnum, bitsize);
-  bitnum = fold_build2 (LSHIFT_EXPR, type, size_one_node, bitnum);
+  bitnum = fold_build2 (LSHIFT_EXPR, type, build_one_cst (type), bitnum);
 
   /* cond = ptr[bitnum / size] & mask;  */
   tree cond = fold_build2 (BIT_AND_EXPR, type, ptr, bitnum);
 
   /* cond ? -1 : 0;  */
   cond = build_condition (TREE_TYPE (callexp), d_truthvalue_conversion (cond),
-                        integer_minus_one_node, integer_zero_node);
+                         build_minus_one_cst (TREE_TYPE (callexp)),
+                         build_zero_cst (TREE_TYPE (callexp)));
 
   /* Update the bit as needed, only testing the bit for bt().  */
   tree_code code;
index ae281d5594621c964d73ac2773c12872a6452ae6..2120dabae714bd19fb301a154036822eeec0e786 100644 (file)
@@ -1173,6 +1173,42 @@ layout_classinfo (ClassDeclaration *cd)
   return v.result ();
 }
 
+/* Get the offset to the BC's vtbl[] initializer from the start of CD.
+   Returns "~0u" if the base class is not found in any vtable interfaces.  */
+
+unsigned
+base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
+{
+  unsigned csymoffset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
+  unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
+  csymoffset += cd->vtblInterfaces->length * interfacesize;
+
+  for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
+    {
+      BaseClass *b = (*cd->vtblInterfaces)[i];
+      if (b == bc)
+       return csymoffset;
+      csymoffset += b->sym->vtbl.length * target.ptrsize;
+    }
+
+  /* Check all overriding interface vtbl[]s.  */
+  for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)
+    {
+      for (size_t k = 0; k < cd2->vtblInterfaces->length; k++)
+       {
+         BaseClass *bs = (*cd2->vtblInterfaces)[k];
+         if (bs->fillVtbl (cd, NULL, 0))
+           {
+             if (bc == bs)
+               return csymoffset;
+             csymoffset += bs->sym->vtbl.length * target.ptrsize;
+           }
+       }
+    }
+
+  return ~0u;
+}
+
 /* Layout fields that immediately come after the classinfo type for DECL if
    there's any interfaces or interface vtables to be added.
    This must be mirrored with base_vtable_offset().  */