Browse Source

Fix ambiguous conversion functions (#1458)

pull/1459/head
josetr 5 years ago committed by GitHub
parent
commit
e61e9201ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 46
      src/Generator/Passes/CheckAmbiguousFunctions.cs
  2. 10
      tests/CSharp/CSharp.Tests.cs
  3. 8
      tests/CSharp/CSharp.cpp
  4. 13
      tests/CSharp/CSharp.h

46
src/Generator/Passes/CheckAmbiguousFunctions.cs

@ -42,18 +42,19 @@ namespace CppSharp.Passes
foreach (var overload in overloads) foreach (var overload in overloads)
{ {
if (function.OperatorKind == CXXOperatorKind.Conversion)
continue;
if (function.OperatorKind == CXXOperatorKind.ExplicitConversion)
continue;
if (overload == function) continue; if (overload == function) continue;
if (!overload.IsGenerated) continue; if (!overload.IsGenerated) continue;
if (CheckConstnessForAmbiguity(function, overload) || var ambiguous =
CheckDefaultParametersForAmbiguity(function, overload) || function.OperatorKind == CXXOperatorKind.Conversion ||
CheckParametersPointerConstnessForAmbiguity(function, overload)) function.OperatorKind == CXXOperatorKind.ExplicitConversion
? CheckConversionAmbiguity(function, overload)
: CheckConstnessForAmbiguity(function, overload) ||
CheckDefaultParametersForAmbiguity(function, overload) ||
CheckParametersPointerConstnessForAmbiguity(function, overload);
if (ambiguous)
{ {
function.IsAmbiguous = true; function.IsAmbiguous = true;
overload.IsAmbiguous = true; overload.IsAmbiguous = true;
@ -172,6 +173,35 @@ namespace CppSharp.Passes
return false; return false;
} }
private bool CheckConversionAmbiguity(Function function, Function overload)
{
var method1 = function as Method;
var method2 = overload as Method;
if (method1 == null || method2 == null)
return false;
var type1 = method1.ReturnType.Type.Desugar();
var type2 = method2.ReturnType.Type.Desugar();
if (type1 is PointerType pointerType1 &&
type2 is PointerType pointerType2)
{
type1 = pointerType1.GetPointee();
type2 = pointerType2.GetPointee();
}
var mappedType1 = type1.GetMappedType(TypeMaps, Options.GeneratorKind);
var mappedType2 = type2.GetMappedType(TypeMaps, Options.GeneratorKind);
if (mappedType1.Equals(mappedType2))
{
method2.ExplicitlyIgnore();
return true;
}
return false;
}
private static bool CheckParametersPointerConstnessForAmbiguity( private static bool CheckParametersPointerConstnessForAmbiguity(
Function function, Function overload) Function function, Function overload)
{ {

10
tests/CSharp/CSharp.Tests.cs

@ -1538,4 +1538,14 @@ public unsafe class CSharpTests : GeneratorTestFixture
Assert.That(out32, Is.EqualTo(cs)); Assert.That(out32, Is.EqualTo(cs));
} }
} }
[Test]
public void TestConversionFunction()
{
using (var c = new ConversionFunctions())
{
Assert.That(*(short*)c, Is.EqualTo(100));
Assert.That((short)c, Is.EqualTo(100));
}
}
} }

8
tests/CSharp/CSharp.cpp

@ -1814,3 +1814,11 @@ const char32_t* TestCSharpString32(const char32_t* in, const char32_t** out)
*out = ret.data(); *out = ret.data();
return ret.data(); return ret.data();
} }
ConversionFunctions::ConversionFunctions() = default;
ConversionFunctions::operator short* () { return &field; }
ConversionFunctions::operator short& () { return field; }
ConversionFunctions::operator short() { return field; }
ConversionFunctions::operator const short*() const { return &field; }
ConversionFunctions::operator const short&() const { return field; }
ConversionFunctions::operator const short() const { return field; }

13
tests/CSharp/CSharp.h

@ -1495,6 +1495,19 @@ struct TestVariableWithoutType
static constexpr auto variable = create(n...); static constexpr auto variable = create(n...);
}; };
struct DLL_API ConversionFunctions
{
ConversionFunctions();
operator short* ();
operator short& ();
operator short();
operator const short*() const;
operator const short&() const;
operator const short() const;
short field = 100;
};
DLL_API const char* TestCSharpString(const char* in, CS_OUT const char** out); DLL_API const char* TestCSharpString(const char* in, CS_OUT const char** out);
DLL_API const wchar_t* TestCSharpStringWide(const wchar_t* in, CS_OUT const wchar_t** out); DLL_API const wchar_t* TestCSharpStringWide(const wchar_t* in, CS_OUT const wchar_t** out);
DLL_API const char16_t* TestCSharpString16(const char16_t* in, CS_OUT const char16_t** out); DLL_API const char16_t* TestCSharpString16(const char16_t* in, CS_OUT const char16_t** out);

Loading…
Cancel
Save