Wrong nullness analysis leads to false positive "condition always true/false" (squid:S2583)

symbolic_execution
java

(Michael Keppler) #1

Version 6.7.4 (build 38452)
SonarJava 5.5 (build 14655)
reproduction example:

package sonar.failure;

import java.util.Random;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
// these annotations are available from https://search.maven.org/#artifactdetails%7Corg.eclipse.jdt%7Corg.eclipse.jdt.annotation%7C2.2.0%7Cjar, but you probably know those, since they are part of your null analysis

@NonNullByDefault
public class SonarqubeFailureReproduction {
    public void failure() {
        final String nullOrNot = nullOrNonNullMethod(new Random().nextBoolean() ? "foo" : null);
        if (nullOrNot == null) {
            System.out.println(
                    "Sonar says this line cannot be reached because the condition is always false. That is wrong.");
        }
    }

    @Nullable
    private String nullOrNonNullMethod(@Nullable final String arg) {
        if (arg == null) {
            return null;
        }
        return nonNullMethod(arg); // the root cause is this line. Sonar concludes that the complete method
                                   // nullOrNonNullMethod() always returns nonNull because of this line.
    }

    @NonNull
    private String nonNullMethod(final String arg) {
        return "" + arg;
    }
}

The conclusioning of Sonar marks these 5 places with red markers:
1 “” + arg
Implies ‘arg’ is not null.
2 nonNullMethod(arg)
‘nonNullMethod()’ returns not null.
3 nullOrNonNullMethod(Random…)
‘nullOrNonNullMethod()’ can return not null.
4 final String nullOrNot
Implies ‘nullOrNot’ can be not null.
5 nullOrNot == null
Expression is always false.


(Andrei Epure) #2

Hi, Michael

Thank you for the detailed reproducer.

I tried to reproduce with the latest SonarJava plugin (5.6.1 build 15064) and could not.

Could you please update your SonarJava plugin and tell us if you can still reproduce this issue?

Thanks,
Andrei