Bug 9028 – `main` is trated sometimes as having C calling convention and sometimes as having D convention

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-11-15T00:59:34Z
Last change time
2024-12-13T18:02:53Z
Keywords
wrong-code
Assigned to
No Owner
Creator
Denis Shelomovskii
Moved to GitHub: dmd#18494 →

Comments

Comment #0 by verylonglogin.reg — 2012-11-15T00:59:34Z
--- void main(string[] args) { if(!args.length) return; foreach(i; 0 .. 1) main(null); // ok, C linkage used foreach(i; 0 .. 1) (&main)(null); // also ok foreach(i; 0 .. 1) { auto p = &main; // D linkage used p(null); // stack corruption, results in Access Violation //asm { add ESP, 0x8; } // uncomment to fix } } --- Note: do not mark `main` as `extern(C)` because it will lead to not calling runtime initialization stuff.
Comment #1 by maxim — 2012-11-15T01:49:06Z
I don't understand what is the problem here. First of all the code runs on both win&lin using dmd 2.060 and git head from Dpaste. Secondly I don't understand how this is related to linkage. Function calls main(null) and (&main)(null) are equivalent. In the third case you call it indirectly through pointer.
Comment #2 by verylonglogin.reg — 2012-11-15T02:01:22Z
(In reply to comment #1) Sorry, it's calling convention, not linkage. I mean C calling convention is used in first two cases but as `typeof(main)` tells it is `extern(D)` D calling convention is used in the last case. So `Access Violation` isn't mandatory but possible. I.e. this will print decreasing ESP: --- import std.stdio; void main(string[] args) { if(!args.length) return; size_t esp; foreach(i; 0 .. 2 ^^ 20) { auto p = &main; // D linkage used p(null); // stack corruption, results in Access Violation //asm { add ESP, 0x8; } // uncomment to fix asm { mov esp, ESP; } writefln("%X", esp); } } ---
Comment #3 by maxim — 2012-11-15T03:11:18Z
Ok, I see the problem now: ------------------------- import std.stdio; void main(string[] args) { dain(args); if(!args.length) return; foreach(i; 0 .. 2) { size_t esp; main(null); // ok, C linkage used asm { mov esp, ESP; } writeln("main"); writefln("%X", esp); } foreach(i; 0 .. 2) { size_t esp; (&main)(null); // also ok asm { mov esp, ESP; } writeln("&main"); writefln("%X", esp); } foreach(i; 0 .. 2) { size_t esp; auto p = &main; // D linkage used p(null); // stack corruption, results in Access Violation //asm { add ESP, 0x8; } // uncomment to fix asm { mov esp, ESP; } writeln("p-main"); writefln("%X", esp); } } void dain(string[] args) { if(!args.length) return; foreach(i; 0 .. 2) { size_t esp; dain(null); // ok, C linkage used asm { mov esp, ESP; } writeln("dain"); writefln("%X", esp); } foreach(i; 0 .. 2) { size_t esp; (&dain)(null); // also ok asm { mov esp, ESP; } writeln("&dain"); writefln("%X", esp); } foreach(i; 0 .. 2) { size_t esp; auto p = &dain; // D linkage used p(null); // stack corruption, results in Access Violation //asm { add ESP, 0x8; } // uncomment to fix asm { mov esp, ESP; } writeln("p-dain"); writefln("%X", esp); } } ---------------------------------- dain 18FDC4 dain 18FDC4 &dain 18FDC4 &dain 18FDC4 p-dain 18FDC4 p-dain 18FDC4 main 18FE10 main 18FE10 &main 18FE10 &main 18FE10 p-main 18FE08 p-main 18FE00 This is windows output. Note in main %esp is decreasing in last loop. Same code on linux is fine (http://dpaste.dzfl.pl/6aa48fed), so this is specific to windows codegen/calling conventions.
Comment #4 by github-bugzilla — 2012-11-15T06:59:22Z
Commit pushed to master at https://github.com/D-Programming-Language/druntime https://github.com/D-Programming-Language/druntime/commit/d171d502d6cb1420140053267cb51989b0f2d07e Add full workaround for Issue 9028. Mark D main as `extern(C)` and use its symbol name to workaround Issue 9028. Also add comments about `D main` type and actual calling convention. * Issue 9028 URL: http://d.puremagic.com/issues/show_bug.cgi?id=9028
Comment #5 by robert.schadek — 2024-12-13T18:02:53Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18494 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB