diff --git a/Cesium.CodeGen.Tests/CodeGenTypeTests.cs b/Cesium.CodeGen.Tests/CodeGenTypeTests.cs index f093c20f..414208e2 100644 --- a/Cesium.CodeGen.Tests/CodeGenTypeTests.cs +++ b/Cesium.CodeGen.Tests/CodeGenTypeTests.cs @@ -395,6 +395,24 @@ int main() { Foo f = { { 1, 2 }, 32 }; return f.a + f.b[0] + f.b[1]; } +"); + + [Fact] + public Task StructVariableInitialization() => DoTest(@"typedef struct Foo { int a; int b; } Foo; +int main() { + int c = 1; + Foo f = { c, 2 }; + return f.a + f.b; +} +"); + + [Fact] + public Task StructCastInitialization() => DoTest(@"typedef struct Foo { int a; int b; } Foo; +int main() { + int c = 1; + Foo f = { (int)c, 2 }; + return f.a + f.b; +} "); [Fact] diff --git a/Cesium.CodeGen.Tests/verified/CodeGenTypeTests.StructCastInitialization.verified.txt b/Cesium.CodeGen.Tests/verified/CodeGenTypeTests.StructCastInitialization.verified.txt new file mode 100644 index 00000000..b9be04fb --- /dev/null +++ b/Cesium.CodeGen.Tests/verified/CodeGenTypeTests.StructCastInitialization.verified.txt @@ -0,0 +1,42 @@ +Module: Primary + Type: + Methods: + System.Int32 ::main() + Locals: + System.Int32 V_0 + Foo V_1 + Foo V_2 + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca V_2 + IL_0006: initobj Foo + IL_000c: ldloca V_2 + IL_0010: ldloc.0 + IL_0011: conv.i4 + IL_0012: stfld System.Int32 Foo::a + IL_0017: ldloca V_2 + IL_001b: ldc.i4.2 + IL_001c: stfld System.Int32 Foo::b + IL_0021: ldloc V_2 + IL_0025: stloc.1 + IL_0026: ldloca.s V_1 + IL_0028: ldfld System.Int32 Foo::a + IL_002d: ldloca.s V_1 + IL_002f: ldfld System.Int32 Foo::b + IL_0034: add + IL_0035: ret + + System.Int32 ::() + Locals: + System.Int32 V_0 + IL_0000: call System.Int32 ::main() + IL_0005: stloc.s V_0 + IL_0007: ldloc.s V_0 + IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32) + IL_000e: ldloc.s V_0 + IL_0010: ret + + Type: Foo + Fields: + System.Int32 Foo::a + System.Int32 Foo::b diff --git a/Cesium.CodeGen.Tests/verified/CodeGenTypeTests.StructVariableInitialization.verified.txt b/Cesium.CodeGen.Tests/verified/CodeGenTypeTests.StructVariableInitialization.verified.txt new file mode 100644 index 00000000..fc912fbc --- /dev/null +++ b/Cesium.CodeGen.Tests/verified/CodeGenTypeTests.StructVariableInitialization.verified.txt @@ -0,0 +1,41 @@ +Module: Primary + Type: + Methods: + System.Int32 ::main() + Locals: + System.Int32 V_0 + Foo V_1 + Foo V_2 + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca V_2 + IL_0006: initobj Foo + IL_000c: ldloca V_2 + IL_0010: ldloc.0 + IL_0011: stfld System.Int32 Foo::a + IL_0016: ldloca V_2 + IL_001a: ldc.i4.2 + IL_001b: stfld System.Int32 Foo::b + IL_0020: ldloc V_2 + IL_0024: stloc.1 + IL_0025: ldloca.s V_1 + IL_0027: ldfld System.Int32 Foo::a + IL_002c: ldloca.s V_1 + IL_002e: ldfld System.Int32 Foo::b + IL_0033: add + IL_0034: ret + + System.Int32 ::() + Locals: + System.Int32 V_0 + IL_0000: call System.Int32 ::main() + IL_0005: stloc.s V_0 + IL_0007: ldloc.s V_0 + IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32) + IL_000e: ldloc.s V_0 + IL_0010: ret + + Type: Foo + Fields: + System.Int32 Foo::a + System.Int32 Foo::b diff --git a/Cesium.CodeGen/Ir/Expressions/CompoundObjectInitializationExpression.cs b/Cesium.CodeGen/Ir/Expressions/CompoundObjectInitializationExpression.cs index 08274934..5c40bc3a 100644 --- a/Cesium.CodeGen/Ir/Expressions/CompoundObjectInitializationExpression.cs +++ b/Cesium.CodeGen/Ir/Expressions/CompoundObjectInitializationExpression.cs @@ -111,7 +111,7 @@ public void EmitTo(IEmitScope scope) if (init == null) throw new CompilationException($"Retrieved null initializer!"); - if (init is ConstantLiteralExpression) + if (init is ConstantLiteralExpression or GetValueExpression or TypeCastExpression) { instructions.Add(Instruction.Create(OpCodes.Ldloca, newobj)); init.EmitTo(scope); diff --git a/Cesium.IntegrationTests/structs/struct_init2.nonportable.c b/Cesium.IntegrationTests/structs/struct_init2.nonportable.c new file mode 100644 index 00000000..17e2522d --- /dev/null +++ b/Cesium.IntegrationTests/structs/struct_init2.nonportable.c @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2025 Cesium contributors + * + * SPDX-License-Identifier: MIT + */ +#include + +typedef struct Foo +{ + int* a; + int b; +} Foo; +int main() { + int c = 33; + Foo f = { NULL, c }; + return (int)f.a + f.b + 9; +}