Skip to content

Commit

Permalink
SONARJAVA-5059 Fix S6901 ClassCastException when methods are called o…
Browse files Browse the repository at this point in the history
…n `this` (#4865)
  • Loading branch information
pauloreilly-sonarsource authored Sep 16, 2024
1 parent 8db836f commit f40dbdc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,21 @@ void falseNegatives(Thread virtualAtRuntime){
outerVirtualThread.setDaemon(true); // False negative
}

class IdentifierTreeImplTest {

SampleThread thread = new SampleThread();

public void test() {
thread.start();
}

private class SampleThread extends Thread {
@Override
public void run() {
setDaemon(true); // generates => mit.methodSelect() instanceof IdentifierTreeImpl
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.check.Rule;
import org.sonar.java.checks.methods.AbstractMethodDetection;
import org.sonar.java.model.ExpressionUtils;
Expand All @@ -37,6 +39,8 @@
@Rule(key = "S6901")
public class VirtualThreadUnsupportedMethodsCheck extends AbstractMethodDetection implements JavaVersionAwareVisitor {

private static final Logger LOG = LoggerFactory.getLogger(VirtualThreadUnsupportedMethodsCheck.class);

private static final String ISSUE_MESSAGE = "Method '%s' is not supported on virtual threads.";
private static final String SECONDARY_LOCATION_ISSUE_MESSAGE = "Virtual thread initialized here.";

Expand Down Expand Up @@ -69,15 +73,22 @@ protected MethodMatchers getMethodInvocationMatchers() {

@Override
protected void onMethodInvocationFound(MethodInvocationTree mit) {
var memberSelect = (MemberSelectExpressionTree) mit.methodSelect();
var expression = memberSelect.expression();
var virtualThreadExpression = getVirtualThreadInitializer(expression);
if (virtualThreadExpression.isPresent()) {
reportIssue(
memberSelect.identifier(),
String.format(ISSUE_MESSAGE, memberSelect.identifier().name()),
List.of(new JavaFileScannerContext.Location(SECONDARY_LOCATION_ISSUE_MESSAGE, ExpressionUtils.methodName(virtualThreadExpression.get()))),
null);
// instance can be IdentifierTreeImpl, for example, so guard against class cast exception
if (mit.methodSelect() instanceof MemberSelectExpressionTree memberSelect) {
var expression = memberSelect.expression();
var virtualThreadExpression = getVirtualThreadInitializer(expression);
if (virtualThreadExpression.isPresent()) {
reportIssue(
memberSelect.identifier(),
String.format(ISSUE_MESSAGE, memberSelect.identifier().name()),
List.of(new JavaFileScannerContext.Location(SECONDARY_LOCATION_ISSUE_MESSAGE,
ExpressionUtils.methodName(virtualThreadExpression.get()))),
null);
}
} else {
LOG.trace("VirtualThreadUnsupportedMethodsCheck.onMethodInvocationFound(): " +
"mit.methodSelect() returns unsupported class instance: {}",
mit.methodSelect().getClass());
}
}

Expand Down

0 comments on commit f40dbdc

Please sign in to comment.