From patchwork Mon Aug 31 14:32:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1354345 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=TKfd9NR/; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BgCN81v0Rz9sTF for ; Tue, 1 Sep 2020 00:32:38 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9874E386F005; Mon, 31 Aug 2020 14:32:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9874E386F005 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1598884355; bh=N3VgEAtpdNn6qtFQx99BsHCjJ0IRHVPuZ7g6VleTowI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=TKfd9NR/sfJ0Tc0LNx96HgksXEHzIlD4aZuqXeAx+tOhS4ZxnJ/MhRHYI4k3WGNUu YiSXNgso+Ia9VeCGOyd0cdANh1h/Y8HxATqZsoy8n8LQfPJOPJSgt2lGmRECeX84u8 20AfK3jptu9WEZD9gg/R7uVe8PPLT9+x5s7MGmbY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [IPv6:2001:67c:2050::465:201]) by sourceware.org (Postfix) with ESMTPS id B18EB386F001 for ; Mon, 31 Aug 2020 14:32:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B18EB386F001 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4BgCMx72lVzQlWG; Mon, 31 Aug 2020 16:32:29 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter05.heinlein-hosting.de (spamfilter05.heinlein-hosting.de [80.241.56.123]) (amavisd-new, port 10030) with ESMTP id j_ICxgHtwQ6r; Mon, 31 Aug 2020 16:32:26 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Fix ICEs in the front-end when pointer size is 16-bit. Date: Mon, 31 Aug 2020 16:32:24 +0200 Message-Id: <20200831143224.2511601-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: * X-Rspamd-Score: 0.21 / 15.00 / 15.00 X-Rspamd-Queue-Id: E43A5683 X-Rspamd-UID: 3004d5 X-Spam-Status: No, score=-15.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch fixes a couple of ICEs seen when compiling D source code for a 16-bit target. The one I used for testing was xstormy16-elf. 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. Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and committed to mainline. Regards Iain --- 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 | 3 --- gcc/d/d-tree.h | 2 +- gcc/d/decl.cc | 36 ------------------------------------ gcc/d/intrinsics.cc | 7 ++++--- gcc/d/typeinfo.cc | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 43 deletions(-) diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 71156e34a9c..ea425ad897c 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -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)); diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index b01a133fe62..31fe5181912 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -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 *); diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 008a2bb16ab..8e4237dd056 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -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. */ diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index 486db127747..1b12a3ec6fb 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -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; diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index ae281d55946..2120dabae71 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -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(). */