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.
This commit is contained in:
parent
5fa821bba7
commit
5d4b824faf
7 changed files with 58 additions and 36 deletions
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -582,13 +582,21 @@ class CppMangleVisitor : public Visitor
|
|||
//printf("mangle_function(%s)\n", d->toChars());
|
||||
/*
|
||||
* <mangled-name> ::= _Z <encoding>
|
||||
*/
|
||||
buf->writestring("_Z");
|
||||
this->mangle_function_encoding(d);
|
||||
}
|
||||
|
||||
void mangle_function_encoding(FuncDeclaration *d)
|
||||
{
|
||||
//printf("mangle_function_encoding(%s)\n", d->toChars());
|
||||
/*
|
||||
* <encoding> ::= <function name> <bare-function-type>
|
||||
* ::= <data name>
|
||||
* ::= <special-name>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue