Skip to content

Commit

Permalink
[Mono AOT] Fix error when returning zero sized struct (#106013)
Browse files Browse the repository at this point in the history
* Fix error when returning zero sized struct

* Add test

* Fix x64 errors
  • Loading branch information
jkurdek authored Aug 14, 2024
1 parent 236538b commit b0dbee9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1593,7 +1593,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
ret_type = LLVMStructType (members, 1, FALSE);
} else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
/* Empty struct */
ret_type = LLVMVoidType ();
ret_type = LLVMStructType (NULL, 0, FALSE);
} else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
LLVMTypeRef members [2];

Expand All @@ -1610,7 +1610,11 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
case LLVMArgVtypeAsScalar: {
int size = mono_class_value_size (mono_class_from_mono_type_internal (rtype), NULL);
/* LLVM models this by returning an int */
if (size < TARGET_SIZEOF_VOID_P) {
if (size == 0) {
/* Empty struct with LayoutKind attribute and without specified size */
g_assert(cinfo->ret.nslots == 0);
ret_type = LLVMIntType (8);
} else if (size < TARGET_SIZEOF_VOID_P) {
g_assert (cinfo->ret.nslots == 1);
ret_type = LLVMIntType (size * 8);
} else {
Expand Down Expand Up @@ -4946,6 +4950,9 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
/* Empty struct */
break;

if (LLVMTypeOf (lcall) == LLVMStructType (NULL, 0, FALSE))
break;

if (!addresses [ins->dreg])
addresses [ins->dreg] = build_alloca_address (ctx, sig->ret);

Expand Down
29 changes: 29 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_103628/Runtime_103628.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using Xunit;

[StructLayout(LayoutKind.Sequential)]
public struct S1
{
}

[StructLayout(LayoutKind.Auto)]
public struct S2
{
}

public class Runtime_103628
{
public static S1 Get_S1() => new S1();

public static S2 Get_S2() => new S2();

[Fact]
public static void TestEntryPoint()
{
S1 s1 = Get_S1();
S2 s2 = Get_S2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit b0dbee9

Please sign in to comment.