From 5d4b824faf1e5846ec684a74f93912cf347928df Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 12 Nov 2020 15:37:46 +0100 Subject: [PATCH] d: Fix ICE in finish_thunk (PR97644) 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. 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; -- 2.30.2