Skip to content

Commit b0dbee9

Browse files
authored
[Mono AOT] Fix error when returning zero sized struct (#106013)
* Fix error when returning zero sized struct * Add test * Fix x64 errors
1 parent 236538b commit b0dbee9

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/mono/mono/mini/mini-llvm.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
15931593
ret_type = LLVMStructType (members, 1, FALSE);
15941594
} else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
15951595
/* Empty struct */
1596-
ret_type = LLVMVoidType ();
1596+
ret_type = LLVMStructType (NULL, 0, FALSE);
15971597
} else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
15981598
LLVMTypeRef members [2];
15991599

@@ -1610,7 +1610,11 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
16101610
case LLVMArgVtypeAsScalar: {
16111611
int size = mono_class_value_size (mono_class_from_mono_type_internal (rtype), NULL);
16121612
/* LLVM models this by returning an int */
1613-
if (size < TARGET_SIZEOF_VOID_P) {
1613+
if (size == 0) {
1614+
/* Empty struct with LayoutKind attribute and without specified size */
1615+
g_assert(cinfo->ret.nslots == 0);
1616+
ret_type = LLVMIntType (8);
1617+
} else if (size < TARGET_SIZEOF_VOID_P) {
16141618
g_assert (cinfo->ret.nslots == 1);
16151619
ret_type = LLVMIntType (size * 8);
16161620
} else {
@@ -4946,6 +4950,9 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
49464950
/* Empty struct */
49474951
break;
49484952

4953+
if (LLVMTypeOf (lcall) == LLVMStructType (NULL, 0, FALSE))
4954+
break;
4955+
49494956
if (!addresses [ins->dreg])
49504957
addresses [ins->dreg] = build_alloca_address (ctx, sig->ret);
49514958

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.InteropServices;
5+
using Xunit;
6+
7+
[StructLayout(LayoutKind.Sequential)]
8+
public struct S1
9+
{
10+
}
11+
12+
[StructLayout(LayoutKind.Auto)]
13+
public struct S2
14+
{
15+
}
16+
17+
public class Runtime_103628
18+
{
19+
public static S1 Get_S1() => new S1();
20+
21+
public static S2 Get_S2() => new S2();
22+
23+
[Fact]
24+
public static void TestEntryPoint()
25+
{
26+
S1 s1 = Get_S1();
27+
S2 s2 = Get_S2();
28+
}
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<Compile Include="$(MSBuildProjectName).cs" />
7+
</ItemGroup>
8+
</Project>

0 commit comments

Comments
 (0)