From patchwork Fri Nov 13 14:06:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1399810 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=pass (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=Pd4Xcfz4; dkim-atps=neutral Received: from sourceware.org (unknown [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 4CXgHd0Qdjz9sTK for ; Sat, 14 Nov 2020 01:06:21 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 126573A1B80A; Fri, 13 Nov 2020 14:06:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 126573A1B80A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1605276376; bh=33jRYwS7b33iT/q2CglsO5zunF1c+j17cdCViOKrFG4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Pd4Xcfz4a5IkyVYmI2mBX+eM+1QIx4mwZIZAIMGpQuKSzzhxgXDO/TNGCp8HZpxnQ zhtJc8N6F9J89YWM0WXUMY9qIK50H3wqp4yKxkfIgq3Wytocyp3VB886CQwngUPYm6 iixeQ/J/Va67YML8efpjsRwLszOIxPBuBZAjWnbU= 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 14FE63858012 for ; Fri, 13 Nov 2020 14:06:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 14FE63858012 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4CXgHS08vtzQlXb; Fri, 13 Nov 2020 15:06:12 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by gerste.heinlein-support.de (gerste.heinlein-support.de [91.198.250.173]) (amavisd-new, port 10030) with ESMTP id SSK5wWSSoA76; Fri, 13 Nov 2020 15:06:07 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Fix ICE in finish_thunk (PR97644) Date: Fri, 13 Nov 2020 15:06:04 +0100 Message-Id: <20201113140604.1974689-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: X-Rspamd-Score: -0.15 / 15.00 / 15.00 X-Rspamd-Queue-Id: A071A183E X-Rspamd-UID: 224176 X-Spam-Status: No, score=-15.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, 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, Because this what the upstream reference compiler did, thunks for the D front-end were associated with the class definition, so were forced code-gen even if the target function was extern. This has now been changed so there are now only generated if there is a function definition, fixing the ICE that occurred in PR 97644, which was caused by calling expand_thunk() early. Bootstrapped and regression tested on x86_64-linux-gnu, and committed to mainline. Regards Iain. --- gcc/d/ChangeLog: PR d/97644 * dmd/MERGE: Merge upstream dmd 95044d8e4. * d-target.cc (TargetCPP::thunkMangle): New function. * decl.cc (finish_thunk): Don't force expand thunks for external functions. (make_thunk): Emit thunks only if the function has a definition. Generate correct mangling for thunks to C++ classes. gcc/testsuite/ChangeLog: * gdc.dg/pr92216.d: Update scan-assember. --- gcc/d/d-target.cc | 9 ++++++ gcc/d/decl.cc | 56 +++++++++++++++------------------- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/cppmangle.c | 20 +++++++++++- gcc/d/dmd/mangle.h | 1 + gcc/d/dmd/target.h | 2 ++ gcc/testsuite/gdc.dg/pr92216.d | 4 +-- 7 files changed, 58 insertions(+), 36 deletions(-) diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 692fce6a655..cd136524eb9 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -329,6 +329,15 @@ TargetCPP::typeInfoMangle (ClassDeclaration *cd) return cppTypeInfoMangleItanium (cd); } +/* Get mangle name of a this-adjusting thunk to the function declaration FD + at call offset OFFSET for C++ linkage. */ + +const char * +TargetCPP::thunkMangle (FuncDeclaration *fd, int offset) +{ + return cppThunkMangleItanium (fd, offset); +} + /* For a vendor-specific type, return a string containing the C++ mangling. In all other cases, return NULL. */ diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index d668715af59..218f35838fd 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1693,26 +1693,6 @@ finish_thunk (tree thunk, tree function) if (DECL_ONE_ONLY (function)) thunk_node->add_to_same_comdat_group (funcn); - - /* Target assemble_mi_thunk doesn't work across section boundaries - on many targets, instead force thunk to be expanded in gimple. */ - if (DECL_EXTERNAL (function)) - { - /* cgraph::expand_thunk writes over current_function_decl, so if this - could ever be in use by the codegen pass, we want to know about it. */ - gcc_assert (current_function_decl == NULL_TREE); - - if (!stdarg_p (TREE_TYPE (thunk))) - { - thunk_node->create_edge (funcn, NULL, thunk_node->count); - expand_thunk (thunk_node, false, true); - } - - /* Tell the back-end to not bother inlining the function, this is - assumed not to work as it could be referencing symbols outside - of the current compilation unit. */ - DECL_UNINLINABLE (function) = 1; - } } /* Return a thunk to DECL. Thunks adjust the incoming `this' pointer by OFFSET. @@ -1789,12 +1769,11 @@ make_thunk (FuncDeclaration *decl, int offset) DECL_CONTEXT (thunk) = d_decl_context (decl); - /* Thunks inherit the public access of the function they are targetting. - When the function is outside the current compilation unit however, then the - thunk must be kept private to not conflict. */ - TREE_PUBLIC (thunk) = TREE_PUBLIC (function) && !DECL_EXTERNAL (function); - - DECL_EXTERNAL (thunk) = 0; + /* Thunks inherit the public access of the function they are targeting. + Thunks are connected to the definitions of the functions, so thunks are + not produced for external functions. */ + TREE_PUBLIC (thunk) = TREE_PUBLIC (function); + DECL_EXTERNAL (thunk) = DECL_EXTERNAL (function); /* Thunks are always addressable. */ TREE_ADDRESSABLE (thunk) = 1; @@ -1806,18 +1785,31 @@ make_thunk (FuncDeclaration *decl, int offset) DECL_COMDAT (thunk) = DECL_COMDAT (function); DECL_WEAK (thunk) = DECL_WEAK (function); - tree target_name = DECL_ASSEMBLER_NAME (function); - unsigned identlen = IDENTIFIER_LENGTH (target_name) + 14; - const char *ident = XNEWVEC (const char, identlen); - snprintf (CONST_CAST (char *, ident), identlen, - "_DT%u%s", offset, IDENTIFIER_POINTER (target_name)); + /* When the thunk is for an extern C++ function, let C++ do the thunk + generation and just reference the symbol as extern, instead of + forcing a D local thunk to be emitted. */ + const char *ident; + + if (decl->linkage == LINKcpp) + ident = target.cpp.thunkMangle (decl, offset); + else + { + tree target_name = DECL_ASSEMBLER_NAME (function); + unsigned identlen = IDENTIFIER_LENGTH (target_name) + 14; + ident = XNEWVEC (const char, identlen); + + snprintf (CONST_CAST (char *, ident), identlen, + "_DTi%u%s", offset, IDENTIFIER_POINTER (target_name)); + } DECL_NAME (thunk) = get_identifier (ident); SET_DECL_ASSEMBLER_NAME (thunk, DECL_NAME (thunk)); d_keep (thunk); + free (CONST_CAST (char *, ident)); - finish_thunk (thunk, function); + if (!DECL_EXTERNAL (function)) + finish_thunk (thunk, function); /* Add it to the list of thunks associated with the function. */ DECL_LANG_THUNKS (thunk) = NULL_TREE; diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 39e424f2a98..e2a0bab2e4a 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -bec5973b0203c95adbda2a049ccdf3cd3a4378f6 +95044d8e45a4320f07d9c75b4eb30e55688a8195 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c index b361d37f75d..3f571fcb14b 100644 --- a/gcc/d/dmd/cppmangle.c +++ b/gcc/d/dmd/cppmangle.c @@ -582,13 +582,21 @@ class CppMangleVisitor : public Visitor //printf("mangle_function(%s)\n", d->toChars()); /* * ::= _Z + */ + buf->writestring("_Z"); + this->mangle_function_encoding(d); + } + + void mangle_function_encoding(FuncDeclaration *d) + { + //printf("mangle_function_encoding(%s)\n", d->toChars()); + /* * ::= * ::= * ::= */ TypeFunction *tf = (TypeFunction *)d->type; - buf->writestring("_Z"); if (getFuncTemplateDecl(d)) { /* It's an instance of a function template @@ -1132,3 +1140,13 @@ const char *cppTypeInfoMangleItanium(Dsymbol *s) v.cpp_mangle_name(s, false); return buf.extractChars(); } + +const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset) +{ + //printf("cppThunkMangleItanium(%s)\n", fd.toChars()); + OutBuffer buf; + buf.printf("_ZThn%u_", offset); // "Th" means thunk, "n%u" is the call offset + CppMangleVisitor v(&buf, fd->loc); + v.mangle_function_encoding(fd); + return buf.extractChars(); +} diff --git a/gcc/d/dmd/mangle.h b/gcc/d/dmd/mangle.h index 77801abb5f6..c60f4a73440 100644 --- a/gcc/d/dmd/mangle.h +++ b/gcc/d/dmd/mangle.h @@ -20,6 +20,7 @@ struct OutBuffer; // In cppmangle.c const char *toCppMangleItanium(Dsymbol *s); const char *cppTypeInfoMangleItanium(Dsymbol *s); +const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset); // In cppmanglewin.c const char *toCppMangleMSVC(Dsymbol *s); diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index c34826af304..f2a55d6a134 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -19,6 +19,7 @@ class ClassDeclaration; class Dsymbol; class Expression; +class FuncDeclaration; class Parameter; class Type; class TypeTuple; @@ -38,6 +39,7 @@ struct TargetCPP const char *toMangle(Dsymbol *s); const char *typeInfoMangle(ClassDeclaration *cd); + const char *thunkMangle(FuncDeclaration *fd, int offset); const char *typeMangle(Type *t); Type *parameterType(Parameter *p); bool fundamentalType(const Type *t, bool& isFundamental); diff --git a/gcc/testsuite/gdc.dg/pr92216.d b/gcc/testsuite/gdc.dg/pr92216.d index 6a87025a7d0..3aff160f799 100644 --- a/gcc/testsuite/gdc.dg/pr92216.d +++ b/gcc/testsuite/gdc.dg/pr92216.d @@ -1,8 +1,8 @@ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92216 // { dg-options "-I $srcdir/gdc.dg" } // { dg-do compile } -// { dg-final { scan-assembler "_DT(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv\[: \t\n\]" } } -// { dg-final { scan-assembler-not "(.globl|.global)\[ \]+_DT(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv" } } +// { dg-final { scan-assembler "_DTi(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv\[: \t\n\]" } } +// { dg-final { scan-assembler-not "(.globl|.global)\[ \]+_DTi(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv" } } module pr92216; private import imports.pr92216;