d: Fix ICEs in the front-end when pointer size is 16-bit.
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.
This commit is contained in:
parent
f089569851
commit
6940c20bbb
@ -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));
|
||||
|
@ -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 *);
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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(). */
|
||||
|
Loading…
Reference in New Issue
Block a user