Skip to content

Commit

Permalink
fix issue 18984 - Debugging stack struct's which are returned causes …
Browse files Browse the repository at this point in the history
…incorrect debuginfo.

change the names of the hidden return value and the NRVO variable
  • Loading branch information
rainers committed Jun 19, 2018
1 parent f95b301 commit b3c9c56
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 10 deletions.
11 changes: 9 additions & 2 deletions src/dmd/glue.d
Expand Up @@ -917,8 +917,15 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
char[5+4+1] hiddenparam = void;
__gshared int hiddenparami; // how many we've generated so far

sprintf(hiddenparam.ptr,"__HID%d",++hiddenparami);
shidden = symbol_name(hiddenparam.ptr,SCparameter,thidden);
const(char)* name;
if (fd.nrvo_can && fd.nrvo_var)
name = fd.nrvo_var.ident.toChars();
else
{
sprintf(hiddenparam.ptr, "__HID%d", ++hiddenparami);
name = hiddenparam.ptr;
}
shidden = symbol_name(name, SCparameter, thidden);
shidden.Sflags |= SFLtrue | SFLfree;
if (fd.nrvo_can && fd.nrvo_var && fd.nrvo_var.nestedrefs.dim)
type_setcv(&shidden.Stype, shidden.Stype.Tty | mTYvolatile);
Expand Down
27 changes: 19 additions & 8 deletions src/dmd/tocsym.d
Expand Up @@ -137,24 +137,35 @@ Symbol *toSymbol(Dsymbol s)
//printf("VarDeclaration.toSymbol(%s)\n", vd.toChars());
assert(!vd.needThis());

Symbol *s;
const(char)[] id;
import dmd.root.outbuffer : OutBuffer;
OutBuffer buf;
bool isNRVO = false;
if (vd.isDataseg())
{
import dmd.root.outbuffer : OutBuffer;
OutBuffer buf;
mangleToBuffer(vd, &buf);
const length = buf.offset;
const id = buf.peekString();
s = symbol_calloc(id, cast(uint)length);
id = buf.peekString()[0..buf.offset]; // symbol_calloc needs zero termination
}
else
{
const id = vd.ident.toChars();
s = symbol_calloc(id, cast(uint)strlen(id));
id = vd.ident.toString();
if (FuncDeclaration fd = vd.toParent2().isFuncDeclaration())
{
if (fd.nrvo_can && fd.nrvo_var == vd)
{
buf.writestring("__nrvo_");
buf.writestring(id);
id = buf.peekString()[0..buf.offset]; // symbol_calloc needs zero termination
isNRVO = true;
}
}
}
Symbol *s = symbol_calloc(id.ptr, cast(uint)id.length);
s.Salignment = vd.alignment;
if (vd.storage_class & STC.temp)
s.Sflags |= SFLartifical;
if (isNRVO)
s.Sflags |= SFLnodebug;

TYPE *t;
if (vd.storage_class & (STC.out_ | STC.ref_))
Expand Down
43 changes: 43 additions & 0 deletions test/runnable/testpdb.d
Expand Up @@ -39,6 +39,8 @@ void main(string[] args)

testLineNumbers(session, globals);

S18984 s = test18984(session, globals);

source.Release();
session.Release();
globals.Release();
Expand Down Expand Up @@ -87,6 +89,47 @@ void testLineNumbers(IDiaSession session, IDiaSymbol globals)
assert(codeByte == 0x48 || codeByte == 0x5d || codeByte == 0xc3); // should be one of "mov rsp,rbp", "pop rbp" or "ret"
}

///////////////////////////////////////////////
// https://issues.dlang.org/show_bug.cgi?id=18984
// Debugging stack struct's which are returned causes incorrect debuginfo

struct S18984
{
int a, b, c;
}

S18984 test18984(IDiaSession session, IDiaSymbol globals)
{
enum funcName = "testpdb.test18984";
IDiaSymbol funcsym = searchSymbol(globals, funcName);
funcsym || assert(false, funcName ~ " not found");
IDiaEnumSymbols enumSymbols;
HRESULT hr = funcsym.findChildren(SymTagEnum.SymTagNull, "s", NameSearchOptions.nsfCaseSensitive, &enumSymbols);
enumSymbols || assert(false, funcName ~ " no children");
ULONG fetched;
IDiaSymbol symbol;
enumSymbols.Next(1, &symbol, &fetched) == S_OK || assert(false, funcName ~ " no children");
symbol || assert(false, funcName ~ " no child symbol");
assert(enumSymbols);
DWORD loc;
symbol.get_locationType(&loc) == S_OK || assert(false, funcName ~ " no location type");
loc == LocationType.LocIsRegRel || assert(false, funcName ~ " 's' not relative to register");
LONG offset;
symbol.get_offset(&offset) == S_OK || assert(false, funcName ~ " cannot get variable offset");
version(Win64)
offset > 0 || assert(false, funcName ~ " 's' not pointing to hidden argument");
else // Win32 passes hidden argument in EAX, which is stored to [EBP-4] on function entry
offset == -4 || assert(false, funcName ~ " 's' not pointing to hidden argument");

symbol.Release();
enumSymbols.Release();

S18984 s = S18984(1, 2, 3);
s.a = 4;
return s; // NRVO
}

///////////////////////////////////////////////
import core.stdc.stdio;
import core.stdc.wchar_;

Expand Down

0 comments on commit b3c9c56

Please sign in to comment.