mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-15 20:33:14 +01:00
Count the sret register as well when keeping track of how many integer registers
are available for extern(C) functions on x86-64. Interestingly, llvm-g++ seems to have a very similar bug: http://llvm.org/pr4242 (So this breaks ABI-compatibility with llvm-gcc for this corner case, but gains it with gcc...) To clarify, this is about code like this: {{{ struct S { void*[3] data; } struct T { void*[2] data; } // The T should be passed in memory, and p in the last int register. extern(C) S fail(int, int, int, int, T t, void* p) { S s; s.data[0] = t.data[0]; s.data[1] = t.data[1]; s.data[2] = p; return s; } }}} which should generate code functionally equivalent to this: {{{ extern(C) S* succeed(S* s, int, int, int, int, T t, void* p) { s.data[0] = t.data[0]; s.data[1] = t.data[1]; s.data[2] = p; return s; } }}} (with the same definitions for S and T)
This commit is contained in:
@@ -562,7 +562,14 @@ bool X86_64TargetABI::returnInArg(TypeFunction* tf) {
|
||||
return false;
|
||||
|
||||
Classification cl = classify(rt);
|
||||
return cl.isMemory;
|
||||
if (cl.isMemory) {
|
||||
assert(state().int_regs > 0
|
||||
&& "No int registers available when determining sret-ness?");
|
||||
// An sret parameter takes an integer register.
|
||||
state().int_regs--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user