Skip to content

Commit

Permalink
Fix parameterless constructors not being generated for structs (#1783)
Browse files Browse the repository at this point in the history
* Fix parameterless constructors not being generated for structs

* Fix implicit non-trivial default ctor

* Adjust `Ignore` linked issue
  • Loading branch information
Saalvage authored Oct 20, 2023
1 parent b16e809 commit a5afda8
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/Generator/AST/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static bool CheckIgnoreMethod(Method method)
var isEmptyCtor = method.IsConstructor && method.Parameters.Count == 0;

var @class = method.Namespace as Class;
if (@class != null && @class.IsValueType && isEmptyCtor)
if (@class != null && @class.IsValueType && isEmptyCtor && !@class.HasNonTrivialDefaultConstructor)
return true;

if (method.IsDestructor)
Expand Down
3 changes: 2 additions & 1 deletion src/Generator/Generators/CLI/CLIHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,8 @@ public void GenerateFunction(Function function)
public static bool FunctionIgnored(Function function)
{
return TypeIgnored(function.ReturnType.Type) ||
function.Parameters.Any(param => TypeIgnored(param.Type));
function.Parameters.Any(param => TypeIgnored(param.Type)) ||
function is Method { IsConstructor: true, Parameters: { Count: 0 }, Namespace: Class { IsValueType: true } };
}

public static bool TypeIgnored(CppSharp.AST.Type type)
Expand Down
2 changes: 1 addition & 1 deletion src/Generator/Generators/CSharp/CSharpSources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2678,7 +2678,7 @@ public void GenerateMethod(Method method, Class @class)
if (hasBase && !@class.IsValueType)
WriteLineIndent($": this({(method != null ? "(void*) null" : "native")})");

if (@class.IsValueType)
if (@class.IsValueType && method.Parameters.Count > 0)
WriteLineIndent(": this()");
}

Expand Down
3 changes: 0 additions & 3 deletions src/Generator/Types/Std/Stdlib.CSharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,6 @@ public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
string var;
if (ctx.ReturnVarName.LastIndexOf('.') > ctx.ReturnVarName.LastIndexOf("->"))
{
ctx.Before.WriteLine("throw new NotImplementedException(\"This method cannot currently be called because it would " +
"leave the object in an invalid state. See https://github.com/mono/CppSharp/issues/1777\");");

var = Generator.GeneratedIdentifier(ctx.ArgName);
ctx.Before.WriteLine($"fixed (void* {var} = &{ctx.ReturnVarName})");
ctx.Before.WriteOpenBraceAndIndent();
Expand Down
28 changes: 26 additions & 2 deletions tests/dotnet/CSharp/CSharp.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2025,8 +2025,7 @@ public void TestOptionalIntPtr()
}

[Test]
[Ignore("https://github.com/mono/CppSharp/issues/1730")]
public void TestString()
public void TestValueTypeStringMember()
{
var test = new CSharp.ValueType();
Assert.AreEqual(string.Empty, test.StringMember);
Expand All @@ -2036,4 +2035,29 @@ public void TestString()
Assert.AreEqual("test", test.StringMember);
Assert.AreEqual("test2", test.CharPtrMember);
}

[Test]
[Ignore("https://github.com/mono/CppSharp/issues/1786")]
public void TestValueTypeStringMemberDefaulted()
{
CSharp.ValueType test = default;
Assert.AreEqual(string.Empty, test.StringMember);
Assert.AreEqual(null, test.CharPtrMember);
test.StringMember = "test";
test.CharPtrMember = "test2";
Assert.AreEqual("test", test.StringMember);
Assert.AreEqual("test2", test.CharPtrMember);
}

[Test]
public void TestValueTypeStringMemberDefaultedCtor()
{
var test = new CSharp.ValueTypeNoCtor();
Assert.AreEqual(string.Empty, test.StringMember);
Assert.AreEqual(null, test.CharPtrMember);
test.StringMember = "test";
test.CharPtrMember = "test2";
Assert.AreEqual("test", test.StringMember);
Assert.AreEqual("test2", test.CharPtrMember);
}
}
9 changes: 7 additions & 2 deletions tests/dotnet/CSharp/CSharp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1644,9 +1644,14 @@ inline void DLL_API InstantiateOptionalTemplate(Optional<unsigned int>, Optional

CS_VALUE_TYPE class DLL_API ValueType {
public:
// Parameterless ctors are currently not generated for value types.
ValueType(int) { }
ValueType() { }

std::string string_member;
const char* char_ptr_member;
};

CS_VALUE_TYPE class DLL_API ValueTypeNoCtor {
public:
std::string string_member;
const char* char_ptr_member;
};
6 changes: 5 additions & 1 deletion tests/dotnet/Common/Common.CSharp.csproj
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>11.0</LangVersion>
</PropertyGroup>
</Project>

0 comments on commit a5afda8

Please sign in to comment.