V3125. The object was used after it was verified against null. Check lines: N1, N2.


The analyzer detected a possible error that may lead to a null dereference.

The following situation was detected. An object is tested for 'null' first and then used without such a check. It implies one of the two scenarios:

1) An exception will be thrown if the object turns out to be null.

2) The program runs correctly all the time, as the object is never null, and the check is therefore unnecessary.

The first scenario is illustrated by the following example, where an exception is likely to be thrown.

obj = Foo();
if (obj != null)
  obj.Func1();
obj.Func2();

If the 'obj' object turns out to be null, evaluating the 'obj.Func2()' expression will result in an exception. The analyzer displays a warning on this code, mentioning 2 lines. The first line is where the object is used; the second is where it is tested for 'null'.

Fixed code:

obj = Foo();
if (obj != null) {
  obj.Func1();
  obj.Func2();
}

The second scenario is illustrated by the following example. The list is iterated in a safe way, so the check can be omitted:

List<string> list = CreateNotEmptyList();
if (list == null || list.Count == 0) { .... }
  foreach (string item in list) { .... }

This code works properly all the time. The 'list' list is never empty. However, the analyzer failed to figure this out and produced a warning. To remove the warning, delete the "if (list == null || list.Count == 0)" check: this operation is meaningless and may confuse the programmer who will be maintaining the code.

Fixed code:

List<string> list = CreateNotEmptyList();
foreach (string item in list) { .... }

Another case where analyzer generates warning is when the null check and the variable's use are situated in the different branches of if\else or switch sections. For example:

if (lines.Count == 1)
{
    if (obj != null)
        obj.Func1();
}
else
{
    lines.Clear();
    obj.Func2();
}

In this case, despite the fact that both branches will not be executed simultaneously - only one branch will be selected for the execution, the null check in one of them indirectly indicates a possibility of a variable receiving null value in other branch as well. Therefore, if control flows to that branch, exception will be generated.

Corrected variant:

if (lines.Count == 1)
{
    if (obj != null)
        obj.Func1();
}
else
{
    lines.Clear();
    if (obj != null)
        obj.Func2();
}

Instead of changing the code, you can add a special comment to suppress false warnings. For the example above, you would have to use the following comment: "obj.Foo(); //-V3125".

According to Common Weakness Enumeration, potential errors found by using this diagnostic are classified as CWE-476.

You can look at examples of errors detected by the V3125 diagnostic.


Bugs Found

Checked Projects
363
Collected Errors
13 495