dmd
dmd copied to clipboard
Fix Issue 21158 - DWARF: function arguments are represented in reverse order
Thanks for your pull request and interest in making D better, @Luhrel! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Please verify that your PR follows this checklist:
- My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
- My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
- I have provided a detailed rationale explaining my changes
- New or modified functions have Ddoc comments (with
Params:andReturns:)
Please see CONTRIBUTING.md for more information.
If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.
Bugzilla references
| Auto-close | Bugzilla | Severity | Description |
|---|---|---|---|
| ✓ | 21158 | trivial | DWARF: function arguments are represented in reverse order |
Testing this PR locally
If you don't have a local development environment setup, you can use Digger to test this PR:
dub run digger -- build "master + dmd#11630"
The argument reversal (ABI-wise) is restricted to extern(D) (and no , ... variadics), and that looks not to be accounted for. The this/context pointer is always the first param, not reversed.
The argument reversal (ABI-wise) is restricted to
extern(D)(and no, ...variadics), and that looks not to be accounted for. Thethis/context pointer is always the first param, not reversed.
I think I get it done in the right way now.
The commit title needs to be Fix [Issue] XXX, the PR title doesn't matter to the bot (because changelog is generated from git log), which is why you can see a little cross in the "Auto-Close" column of the bot's message.
The commit title needs to be
Fix [Issue] XXX, the PR title doesn't matter to the bot (because changelog is generated from git log), which is why you can see a little cross in the "Auto-Close" column of the bot's message.
Good to know.
I think I get it done in the right way now.
Have you checked the this pointer for methods? Another implicit, non-formal param is the sret pointer in case the return value is allocated and its address passed by the caller (e.g., for non-POD return types such as a struct with dtor). - I've seen that you compare the DMD DWARF emission to LDC's; I think the better reference is probably GDC, as Iain has put quite some effort into a nice debugging experience AFAIK.
@kinke @WalterBright Any objections to this addition?
I'm still looking for an sret test, preferrably including a combined sret+this testcase, and a test for a nested function receiving an implicit context pointer.
@Luhrel please give me a ping when you have added the test required by @kinke . Thanks!
ping @RazvanN7.
It seems that the nested function test is still missing.
@RazvanN7 Should be good now.
Still no sret tests.
Something like:
struct S
{
int x;
~this() {}
S foo(int a, float b)
{
// breakpoint here; expected low-level params order: `<sret pointer>, <this pointer>, b, a`
return S(x + a);
}
}
Something like:
struct S { int x; ~this() {} S foo(int a, float b) { // breakpoint here; expected low-level params order: `<sret pointer>, <this pointer>, b, a` return S(x + a); } }
Oh ok. Now I have no idea how to check if a Symbol is a sret pointer. The backend isn't as clear as the frontend, unfortunately.
Any help is welcome.
You're probably looking for this: https://github.com/dlang/dmd/blob/71d410d365edcfac8cd9c7878363dac81a0728e5/src/dmd/backend/cc.d#L749 (should be in sfunc.Sfunc.Fflags3 too).
That flag isn't set in this test case (but the sret argument is there, so I'm a bit confused) 🤔
It seems that this is the only place where F3hiddenPtr is set. Maybe you can check if @kinke 's code reaches that path. If yes, the only place where F3hiddenPtr is checked is here.
Maybe it does get set but it somehow gets zeroed along the way. Otherwise, there might be another param or combination of params that tells us if a function requires a sret or not.
Hope this helps.
It seems that this is the only place where
F3hiddenPtris set. Maybe you can check if @kinke 's code reaches that path. If yes, the only place whereF3hiddenPtris checked is here.Maybe it does get set but it somehow gets zeroed along the way. Otherwise, there might be another param or combination of params that tells us if a function requires a sret or not.
Hope this helps.
I dug a little bit. F3hiddenPtr is only set for classes.
toObjFile . visit(ClassDeclaration) -> genTypeInfoForClass -> emitVtlb (1/2) -> toThunkSymbol -> Fflags3 |= F3hiddenPtr.
In toObjFile.visit(StructDeclaration), there's nothing about F3hiddenPtr/ Fflags3, so I may be missing here. However, I have a very poor understanding of the backend, so I have no idea what are the consequences of adding it.
Any ideas @kinke ?
I have no idea about DMD's backend either; after a quick glance, it looks like setting the flag (f.Fflags3 |= F3hiddenPtr) might be missing here: https://github.com/dlang/dmd/blob/218d999fdec37f0b3c6e5835554847a158e65ed4/src/dmd/glue.d#L743-L765