From a6ec8b6a2583928472cde6858fcc205d35e4ae3c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Mar 2025 13:31:20 +0100 Subject: [PATCH 1/4] C#: Convert tests cs/useless-gethashcode-call to inline tests. --- .../IntGetHashCode/IntGetHashCode.cs | 16 ++++++++-------- .../IntGetHashCode/IntGetHashCode.qlref | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs index 80b0ed180fc4..ae8d93ef468e 100644 --- a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs +++ b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs @@ -3,14 +3,14 @@ class IntGetHashCode void Test() { // These are all bad: - default(uint).GetHashCode(); - default(int).GetHashCode(); - default(long).GetHashCode(); - default(ulong).GetHashCode(); - default(short).GetHashCode(); - default(ushort).GetHashCode(); - default(byte).GetHashCode(); - default(sbyte).GetHashCode(); + default(uint).GetHashCode(); // $ Alert + default(int).GetHashCode(); // $ Alert + default(long).GetHashCode(); // $ Alert + default(ulong).GetHashCode(); // $ Alert + default(short).GetHashCode(); // $ Alert + default(ushort).GetHashCode(); // $ Alert + default(byte).GetHashCode(); // $ Alert + default(sbyte).GetHashCode(); // $ Alert // These are all good: default(double).GetHashCode(); diff --git a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.qlref b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.qlref index a2aedb412274..710cdadee824 100644 --- a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.qlref +++ b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.qlref @@ -1 +1,2 @@ -Useless code/IntGetHashCode.ql \ No newline at end of file +query: Useless code/IntGetHashCode.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql From 4b021986521ef2baea0ed12d4a53f0fa403d50e8 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Mar 2025 13:32:22 +0100 Subject: [PATCH 2/4] C#: Only consider calling GetHashCode on byte, sbyte, short, ushort and int as useless. --- csharp/ql/src/Useless code/IntGetHashCode.ql | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/csharp/ql/src/Useless code/IntGetHashCode.ql b/csharp/ql/src/Useless code/IntGetHashCode.ql index c7892fffc650..85d0f56aae0e 100644 --- a/csharp/ql/src/Useless code/IntGetHashCode.ql +++ b/csharp/ql/src/Useless code/IntGetHashCode.ql @@ -16,5 +16,12 @@ import semmle.code.csharp.frameworks.System from MethodCall mc, IntegralType t where mc.getTarget() instanceof GetHashCodeMethod and - t = mc.getQualifier().getType() + t = mc.getQualifier().getType() and + ( + t instanceof ByteType or + t instanceof SByteType or + t instanceof ShortType or + t instanceof UShortType or + t instanceof IntType + ) select mc, "Calling GetHashCode() on type " + t.toStringWithTypes() + " is redundant." From 36a524929fe4c80b8b904b8dc75298b722ff8944 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Mar 2025 13:38:13 +0100 Subject: [PATCH 3/4] C#: Update tests and test expected output. --- .../Useless Code/IntGetHashCode/IntGetHashCode.cs | 6 +++--- .../IntGetHashCode/IntGetHashCode.expected | 13 +++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs index ae8d93ef468e..22a24013b08d 100644 --- a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs +++ b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.cs @@ -3,16 +3,16 @@ class IntGetHashCode void Test() { // These are all bad: - default(uint).GetHashCode(); // $ Alert default(int).GetHashCode(); // $ Alert - default(long).GetHashCode(); // $ Alert - default(ulong).GetHashCode(); // $ Alert default(short).GetHashCode(); // $ Alert default(ushort).GetHashCode(); // $ Alert default(byte).GetHashCode(); // $ Alert default(sbyte).GetHashCode(); // $ Alert // These are all good: + default(uint).GetHashCode(); + default(long).GetHashCode(); + default(ulong).GetHashCode(); default(double).GetHashCode(); default(float).GetHashCode(); default(char).GetHashCode(); diff --git a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.expected b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.expected index 6f126779321c..da253cc80b21 100644 --- a/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.expected +++ b/csharp/ql/test/query-tests/Useless Code/IntGetHashCode/IntGetHashCode.expected @@ -1,8 +1,5 @@ -| IntGetHashCode.cs:6:9:6:35 | call to method GetHashCode | Calling GetHashCode() on type uint is redundant. | -| IntGetHashCode.cs:7:9:7:34 | call to method GetHashCode | Calling GetHashCode() on type int is redundant. | -| IntGetHashCode.cs:8:9:8:35 | call to method GetHashCode | Calling GetHashCode() on type long is redundant. | -| IntGetHashCode.cs:9:9:9:36 | call to method GetHashCode | Calling GetHashCode() on type ulong is redundant. | -| IntGetHashCode.cs:10:9:10:36 | call to method GetHashCode | Calling GetHashCode() on type short is redundant. | -| IntGetHashCode.cs:11:9:11:37 | call to method GetHashCode | Calling GetHashCode() on type ushort is redundant. | -| IntGetHashCode.cs:12:9:12:35 | call to method GetHashCode | Calling GetHashCode() on type byte is redundant. | -| IntGetHashCode.cs:13:9:13:36 | call to method GetHashCode | Calling GetHashCode() on type sbyte is redundant. | +| IntGetHashCode.cs:6:9:6:34 | call to method GetHashCode | Calling GetHashCode() on type int is redundant. | +| IntGetHashCode.cs:7:9:7:36 | call to method GetHashCode | Calling GetHashCode() on type short is redundant. | +| IntGetHashCode.cs:8:9:8:37 | call to method GetHashCode | Calling GetHashCode() on type ushort is redundant. | +| IntGetHashCode.cs:9:9:9:35 | call to method GetHashCode | Calling GetHashCode() on type byte is redundant. | +| IntGetHashCode.cs:10:9:10:36 | call to method GetHashCode | Calling GetHashCode() on type sbyte is redundant. | From dff66c7b2820df301f979e46e02396bb09c9cfb3 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Mar 2025 13:42:58 +0100 Subject: [PATCH 4/4] C#: Add change-note. --- .../src/change-notes/2025-03-13-useless-gethashcode-call.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2025-03-13-useless-gethashcode-call.md diff --git a/csharp/ql/src/change-notes/2025-03-13-useless-gethashcode-call.md b/csharp/ql/src/change-notes/2025-03-13-useless-gethashcode-call.md new file mode 100644 index 000000000000..55b705b79ecb --- /dev/null +++ b/csharp/ql/src/change-notes/2025-03-13-useless-gethashcode-call.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Increase query precision for `cs/useless-gethashcode-call` by not flagging calls to `GetHashCode` on `uint`, `long` and `ulong`.