Compare commits

...

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
0bc0c59a14 Add test cases for nullable Equals methods
Adds test cases for Equals methods with nullable reference type parameters
(object?) to verify the fix works correctly.

Co-authored-by: hvitved <3667920+hvitved@users.noreply.github.com>
2026-02-16 10:35:29 +00:00
copilot-swe-agent[bot]
fdbc72a673 Remove ObjectType parameter checks from System.qll methods
Removes instanceof ObjectType checks from method signatures in System.qll to support
nullable reference types (object?). This fixes false positives when Equals(object?)
is used instead of Equals(object), as they are the same underlying type with different
nullability annotations.

Fixes:
- SystemIComparableInterface.getCompareToMethod()
- SystemObjectClass.getEqualsMethod()
- SystemObjectClass.getStaticEqualsMethod()
- SystemObjectClass.getReferenceEqualsMethod()

Co-authored-by: hvitved <3667920+hvitved@users.noreply.github.com>
2026-02-16 10:34:49 +00:00
copilot-swe-agent[bot]
c20b948b3f Initial plan 2026-02-16 10:25:49 +00:00
4 changed files with 61 additions and 6 deletions

View File

@@ -144,7 +144,6 @@ class SystemIComparableInterface extends SystemInterface {
result.getDeclaringType() = this and
result.hasName("CompareTo") and
result.getNumberOfParameters() = 1 and
result.getParameter(0).getType() instanceof ObjectType and
result.getReturnType() instanceof IntType
}
}
@@ -263,7 +262,6 @@ class SystemObjectClass extends SystemClass instanceof ObjectType {
result.getDeclaringType() = this and
result.hasName("Equals") and
result.getNumberOfParameters() = 1 and
result.getParameter(0).getType() instanceof ObjectType and
result.getReturnType() instanceof BoolType
}
@@ -273,8 +271,6 @@ class SystemObjectClass extends SystemClass instanceof ObjectType {
result.getDeclaringType() = this and
result.hasName("Equals") and
result.getNumberOfParameters() = 2 and
result.getParameter(0).getType() instanceof ObjectType and
result.getParameter(1).getType() instanceof ObjectType and
result.getReturnType() instanceof BoolType
}
@@ -284,8 +280,6 @@ class SystemObjectClass extends SystemClass instanceof ObjectType {
result.getDeclaringType() = this and
result.hasName("ReferenceEquals") and
result.getNumberOfParameters() = 2 and
result.getParameter(0).getType() instanceof ObjectType and
result.getParameter(1).getType() instanceof ObjectType and
result.getReturnType() instanceof BoolType
}

View File

@@ -24,3 +24,16 @@ struct Equals1Struct
{
public override bool Equals(object other) => false;
}
#nullable enable
class NullableEquals1
{
public override bool Equals(object? other) => false;
}
class NullableEquals2 : IEquatable<NullableEquals2>
{
public bool Equals(NullableEquals2? other) => other != null;
public override bool Equals(object? other) => other is NullableEquals2 n && Equals(n);
}

View File

@@ -5,3 +5,5 @@
| Equals.cs:16:7:16:13 | Equals3 | Equals3.Equals(Equals3) | true |
| Equals.cs:21:8:21:21 | NoEqualsStruct | System.ValueType.Equals(object) | false |
| Equals.cs:23:8:23:20 | Equals1Struct | Equals1Struct.Equals(object) | true |
| Equals.cs:31:7:31:21 | NullableEquals1 | NullableEquals1.Equals(object) | true |
| Equals.cs:36:7:36:21 | NullableEquals2 | NullableEquals2.Equals(NullableEquals2) | true |

View File

@@ -0,0 +1,46 @@
using System;
#nullable enable
namespace Test
{
class TestClass1 : IEquatable<TestClass1>
{
private int field1;
public bool Equals(TestClass1? param1)
{
return param1 != null && field1 == param1.field1;
}
public override bool Equals(object? param2)
{
return param2 is TestClass1 tc && Equals(tc);
}
public override int GetHashCode()
{
return field1;
}
}
class TestClass2
{
private string field2;
public TestClass2(string s)
{
field2 = s;
}
public override bool Equals(object? param3)
{
return param3 is TestClass2 tc && field2 == tc.field2;
}
public override int GetHashCode()
{
return field2?.GetHashCode() ?? 0;
}
}
}