Dead stores should be removed - false positive in a loop

We’re using SonarQube version 6.7.5 (build 38563) and the following code gets flagged by the “Dead stores should be removed” rule:

        int retriesLeft = maxRetries;
        int currentBackoffInMillis = backoffInMillis;
        while (true) {
            try {
                return function.get();
            } catch (CommunicationException e) {
                if (retriesLeft == 0) {
                    throw e;
                }
                onRetryListener.onRetry(e, currentBackoffInMillis);
                CommonUtil.sleep(currentBackoffInMillis);

                currentBackoffInMillis *= 2;
                retriesLeft--;
            }
        }

It says that the values of retriesLeft and currentBackoffInMillis are not read after they’re written, but the values are obviously used in the body of the catch block.
This false positive is also reproducible with version 4.1.0.201901311043 of the SonarLint extension for Eclipse.

Hi,

What’s your version of SonarJava (Administration > Marketplace)?

 
Ann

Hi Ann,

Unfortunately, I don’t see this menu - maybe I need more privileges. :frowning:

Isn’t the version of the Eclipse extension sufficient? It shows the same false positive and I assume that it also uses this “SonarJava”.

Hi,

If you’re in connected mode, you’ll be using the version of SonarJava that’s loaded on your server. Try this call: api/plugins/installed (but please don’t give me the whole output :smile:).

 
Ann

Sorry for the delay! This is the version of SonarJava:

      {  
         "key":"java",
         "name":"SonarJava",
         "filename":"sonar-java-plugin-5.11.0.17289.jar",
         "sonarLintSupported":true,
         "hash":"7b8427a6d19d134933df94d4625db54c",
         "updatedAt":1552391385139,
         "description":"Code Analyzer for Java",
         "version":"5.11 (build 17289)",
         "license":"GNU LGPL 3",
         "organizationName":"SonarSource",
         "organizationUrl":"http://www.sonarsource.com",
         "editionBundled":false,
         "homepageUrl":"http://redirect.sonarsource.com/plugins/java.html",
         "issueTrackerUrl":"https://jira.sonarsource.com/browse/SONARJAVA",
         "implementationBuild":"af4a10d32a35370facd63e239fd8d452d981798a"
      }

BTW, how can I check whether my SonarLint extension is in connected mode? I don’t remember setting up any connections to the Sonar server.

Hi,

Four hours is hardly a delay! :smile:

Someone other than me will come back to you on this topic.

 
:slight_smile:
Ann

Hello @nictas,

I didn’t manage to reproduce the issue, can you try to create code sample reproducing the issue and having all the symbols declared (i.e. its compilable)?

I tried the following snippet, which is imo equivalent and issue is not reported.

abstract class S1854 {

  void test() {
    int x = 42;
    while (true) {
      try {
        bar();
      } catch (Exception e) {
        if (x == 0) {
          throw e;
        }
        x--;
      }
    }
  }

  abstract void bar();
}

Hi Tibor,

Thanks for taking a look! You should be able to reproduce the issue with this code fragment:

public abstract class S1854 {

    private int maxRetries = 10;
    private int backoffInMillis = 1000;
    private OnRetryListener onRetryListener = (e, backoffInMillis) -> {
    };

    <T> T test(SupplierWithCheckedException<T, FooException> supplier) throws FooException {
        int retriesLeft = maxRetries;
        int currentBackoffInMillis = backoffInMillis;
        while (true) {
            try {
                return supplier.get();
            } catch (FooException e) {
                if (retriesLeft == 0) {
                    throw e;
                }
                onRetryListener.onRetry(e, currentBackoffInMillis);
                sleep(currentBackoffInMillis);

                currentBackoffInMillis *= 2;
                retriesLeft--;
            }
        }
    }

    abstract void sleep(int millis);

    @FunctionalInterface
    private static interface SupplierWithCheckedException<T, E extends Exception> {

        T get() throws E;

    }

    @FunctionalInterface
    public static interface OnRetryListener {

        void onRetry(FooException e, long backoffInMillis);

    }

    public class FooException extends Exception {

        private static final long serialVersionUID = 1L;

        public FooException() {
            super();
        }

        public FooException(String message, Throwable cause) {
            super(message, cause);
        }

        public FooException(String message) {
            super(message);
        }

    }

}

I’m also attaching a screenshot of the problem from SonarQube’s UI:


My Eclipse plugins are:
SonarLint Core - Client API 4.1.0.2218
SonarLint Core - Implementation 4.1.0.2218
SonarLint for Eclipse 4.1.0.201901311043
SonarLint for Eclipse CDT 4.1.0.201901311043
SonarLint for Eclipse Core 4.1.0.201901311043
SonarLint for Eclipse JDT 4.1.0.201901311043
SonarLint for Eclipse m2e 4.1.0.201901311043

Second screenshot from my Eclipse IDE (new users can only upload once per post :frowning:):

@saberduck Were you able to reproduce it?

Hello,

yes, I was able to reproduce with your sample I created the ticket
https://jira.sonarsource.com/browse/SONARJAVA-3080

It seems to be an issue with CFG construction and handling of exceptions.Thanks for reporting it.