C#: Convert tests for cs/dereferenced-value-is-always-null to use inline expectations.

This commit is contained in:
Michael Nebel
2025-05-27 09:53:44 +02:00
parent 5e84c71b69
commit 46c02e7fa8
9 changed files with 47 additions and 46 deletions

View File

@@ -5,7 +5,7 @@ class A
public void Lock() public void Lock()
{ {
object synchronizedAlways = null; object synchronizedAlways = null;
lock (synchronizedAlways) // BAD (always) lock (synchronizedAlways) // $ Alert[cs/dereferenced-value-is-always-null]
{ {
synchronizedAlways.GetHashCode(); // GOOD synchronizedAlways.GetHashCode(); // GOOD
} }
@@ -14,7 +14,7 @@ class A
public void ArrayAssignTest() public void ArrayAssignTest()
{ {
int[] arrayNull = null; int[] arrayNull = null;
arrayNull[0] = 10; // BAD (always) arrayNull[0] = 10; // $ Alert[cs/dereferenced-value-is-always-null]
int[] arrayOk; int[] arrayOk;
arrayOk = new int[10]; arrayOk = new int[10];
@@ -28,10 +28,10 @@ class A
object methodAccess = null; object methodAccess = null;
object methodCall = null; object methodCall = null;
Console.WriteLine(arrayAccess[1]); // BAD (always) Console.WriteLine(arrayAccess[1]); // $ Alert[cs/dereferenced-value-is-always-null]
Console.WriteLine(fieldAccess.Length); // BAD (always) Console.WriteLine(fieldAccess.Length); // $ Alert[cs/dereferenced-value-is-always-null]
Func<String> tmp = methodAccess.ToString; // BAD (always) Func<String> tmp = methodAccess.ToString; // $ Alert[cs/dereferenced-value-is-always-null]
Console.WriteLine(methodCall.ToString()); // BAD (always) Console.WriteLine(methodCall.ToString()); // $ Alert[cs/dereferenced-value-is-always-null]
Console.WriteLine(arrayAccess[1]); // GOOD Console.WriteLine(arrayAccess[1]); // GOOD
Console.WriteLine(fieldAccess.Length); // GOOD Console.WriteLine(fieldAccess.Length); // GOOD
@@ -47,7 +47,7 @@ class A
object varRef = null; object varRef = null;
TestMethod2(ref varRef); TestMethod2(ref varRef);
varRef.ToString(); // BAD (always) varRef.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
varRef = null; varRef = null;
TestMethod3(ref varRef); TestMethod3(ref varRef);

View File

@@ -12,7 +12,7 @@ class AssertTests
s = b ? null : ""; s = b ? null : "";
Assert.IsNull(s); Assert.IsNull(s);
Console.WriteLine(s.Length); // BAD (always) Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : ""; s = b ? null : "";
Assert.IsNotNull(s); Assert.IsNotNull(s);
@@ -20,7 +20,7 @@ class AssertTests
s = b ? null : ""; s = b ? null : "";
Assert.IsTrue(s == null); Assert.IsTrue(s == null);
Console.WriteLine(s.Length); // BAD (always) Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : ""; s = b ? null : "";
Assert.IsTrue(s != null); Assert.IsTrue(s != null);
@@ -28,7 +28,7 @@ class AssertTests
s = b ? null : ""; s = b ? null : "";
Assert.IsFalse(s != null); Assert.IsFalse(s != null);
Console.WriteLine(s.Length); // BAD (always) Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : ""; s = b ? null : "";
Assert.IsFalse(s == null); Assert.IsFalse(s == null);
@@ -44,10 +44,10 @@ class AssertTests
s = b ? null : ""; s = b ? null : "";
Assert.IsTrue(s == null && b); Assert.IsTrue(s == null && b);
Console.WriteLine(s.Length); // BAD (always) Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : ""; s = b ? null : "";
Assert.IsFalse(s != null || !b); Assert.IsFalse(s != null || !b);
Console.WriteLine(s.Length); // BAD (always) Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
} }
} }

View File

@@ -10,7 +10,7 @@ class B
B neqCallAlways = null; B neqCallAlways = null;
if (eqCallAlways == null) if (eqCallAlways == null)
eqCallAlways.ToString(); // BAD (always) eqCallAlways.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
if (b2 != null) if (b2 != null)
b2.ToString(); // GOOD b2.ToString(); // GOOD
@@ -21,7 +21,7 @@ class B
if (neqCallAlways != null) { } if (neqCallAlways != null) { }
else else
neqCallAlways.ToString(); // BAD (always) neqCallAlways.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
public static bool operator ==(B b1, B b2) public static bool operator ==(B b1, B b2)

View File

@@ -15,7 +15,7 @@ public class C
if (!(o != null)) if (!(o != null))
{ {
o.GetHashCode(); // BAD (always) o.GetHashCode(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
} }
@@ -39,7 +39,7 @@ public class C
{ {
var s = Maybe() ? null : ""; var s = Maybe() ? null : "";
Debug.Assert(s == null); Debug.Assert(s == null);
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = Maybe() ? null : ""; s = Maybe() ? null : "";
Debug.Assert(s != null); Debug.Assert(s != null);
@@ -50,11 +50,11 @@ public class C
{ {
var o1 = new object(); var o1 = new object();
AssertNull(o1); AssertNull(o1);
o1.ToString(); // BAD (always) (false negative) o1.ToString(); // $ MISSING: Alert[cs/dereferenced-value-is-always-null]
var o2 = Maybe() ? null : ""; var o2 = Maybe() ? null : "";
Assert.IsNull(o2); Assert.IsNull(o2);
o2.ToString(); // BAD (always) o2.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
public void AssertNotNullTest() public void AssertNotNullTest()
@@ -159,7 +159,7 @@ public class C
s = null; s = null;
do do
{ {
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = null; s = null;
} }
while (s != null); while (s != null);
@@ -167,7 +167,7 @@ public class C
s = null; s = null;
do do
{ {
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
while (s != null); while (s != null);
@@ -193,7 +193,7 @@ public class C
s = null; s = null;
while (b) while (b)
{ {
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = null; s = null;
} }
@@ -215,7 +215,7 @@ public class C
} }
if (s == null) if (s == null)
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = ""; s = "";
if (s != null && s.Length % 2 == 0) if (s != null && s.Length % 2 == 0)
@@ -230,11 +230,11 @@ public class C
{ {
s.ToString(); // GOOD s.ToString(); // GOOD
} }
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
for (s = null; s == null; s = null) for (s = null; s == null; s = null)
{ {
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
for (s = ""; ; s = null) for (s = ""; ; s = null)
@@ -246,7 +246,7 @@ public class C
public void ArrayAssignTest() public void ArrayAssignTest()
{ {
int[] a = null; int[] a = null;
a[0] = 10; // BAD (always) a[0] = 10; // $ Alert[cs/dereferenced-value-is-always-null]
a = new int[10]; a = new int[10];
a[0] = 42; // GOOD a[0] = 42; // GOOD
@@ -257,8 +257,8 @@ public class C
int[] ia = null; int[] ia = null;
string[] sa = null; string[] sa = null;
ia[1] = 0; // BAD (always) ia[1] = 0; // $ Alert[cs/dereferenced-value-is-always-null]
var temp = sa.Length; // BAD (always) var temp = sa.Length; // $ Alert[cs/dereferenced-value-is-always-null]
ia[1] = 0; // BAD (always), but not first ia[1] = 0; // BAD (always), but not first
temp = sa.Length; // BAD (always), but not first temp = sa.Length; // BAD (always), but not first

View File

@@ -117,7 +117,7 @@ public class D
var x = b ? null : "abc"; var x = b ? null : "abc";
x = x == null ? "" : x; x = x == null ? "" : x;
if (x == null) if (x == null)
x.ToString(); // BAD (always) x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
else else
x.ToString(); // GOOD x.ToString(); // GOOD
} }
@@ -194,7 +194,7 @@ public class D
{ {
var o = new Object(); var o = new Object();
if (o == null) if (o == null)
o.ToString(); // BAD (always) o.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
o.ToString(); // GOOD o.ToString(); // GOOD
try try
@@ -204,7 +204,7 @@ public class D
catch (Exception e) catch (Exception e)
{ {
if (e == null) if (e == null)
e.ToString(); // BAD (always) e.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
e.ToString(); // GOOD e.ToString(); // GOOD
} }
@@ -214,12 +214,12 @@ public class D
var o3 = "abc"; var o3 = "abc";
if (o3 == null) if (o3 == null)
o3.ToString(); // BAD (always) o3.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
o3.ToString(); // GOOD o3.ToString(); // GOOD
var o4 = "" + null; var o4 = "" + null;
if (o4 == null) if (o4 == null)
o4.ToString(); // BAD (always) o4.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
o4.ToString(); // GOOD o4.ToString(); // GOOD
} }
@@ -382,7 +382,7 @@ public class D
if (ioe != null) if (ioe != null)
ioe = e; ioe = e;
else else
ioe.ToString(); // BAD (always) ioe.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
public void LengthGuard2(int[] a, int[] b) public void LengthGuard2(int[] a, int[] b)

View File

@@ -207,7 +207,7 @@ public class E
{ {
if (s is string) if (s is string)
return s.Length; return s.Length;
return s.GetHashCode(); // BAD (always) return s.GetHashCode(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
public void Ex15(bool b) public void Ex15(bool b)
@@ -217,7 +217,7 @@ public class E
x = null; x = null;
x.ToString(); // BAD (maybe) x.ToString(); // BAD (maybe)
if (b) if (b)
x.ToString(); // BAD (always) x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
public void Ex16(bool b) public void Ex16(bool b)
@@ -226,7 +226,7 @@ public class E
if (b) if (b)
x = null; x = null;
if (b) if (b)
x.ToString(); // BAD (always) x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
x.ToString(); // BAD (maybe) x.ToString(); // BAD (maybe)
} }
@@ -320,15 +320,15 @@ public class E
{ {
if ((s1 ?? s2) is null) if ((s1 ?? s2) is null)
{ {
s1.ToString(); // BAD (always) s1.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s2.ToString(); // BAD (always) s2.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
} }
static void Ex28() static void Ex28()
{ {
var x = (string)null ?? null; var x = (string)null ?? null;
x.ToString(); // BAD (always) x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
static void Ex29(string s) static void Ex29(string s)
@@ -402,7 +402,7 @@ public class E
{ {
int? i = null; int? i = null;
i ??= null; i ??= null;
return i.Value; // BAD (always) return i.Value; // $ Alert[cs/dereferenced-value-is-always-null]
} }
int Ex41() int Ex41()
@@ -436,12 +436,12 @@ public class E
{ {
if (s is null) if (s is null)
{ {
s.ToString(); // BAD (always) s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
} }
if (s is not not null) if (s is not not null)
{ {
s.ToString(); // BAD (always) (FALSE NEGATIVE) s.ToString(); // $ MISSING: Alert[cs/dereferenced-value-is-always-null]
} }
if (s is not null) if (s is not null)

View File

@@ -33,11 +33,11 @@ class ForwardingTests
if (IsNotNullWrong(s)) if (IsNotNullWrong(s))
{ {
Console.WriteLine(s.Length); // BAD (always) Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
} }
AssertIsNotNull(s); AssertIsNotNull(s);
Console.WriteLine(s.Length); // GOOD (false positive) Console.WriteLine(s.Length); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-is-always-null]
} }
bool IsNotNull(object o) bool IsNotNull(object o)

View File

@@ -1 +1,2 @@
CSI/NullAlways.ql query: CSI/NullAlways.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -6,7 +6,7 @@ namespace NullAlways
{ {
void DoPrint(string s) void DoPrint(string s)
{ {
if (s != null || s.Length > 0) if (s != null || s.Length > 0) // $ Alert[cs/dereferenced-value-is-always-null]
Console.WriteLine(s); Console.WriteLine(s);
} }
} }