Skip to content

Commit

Permalink
Fix for detector UncallableMethodOfAnonymousClass to not report unu…
Browse files Browse the repository at this point in the history
…sed methods of method-local enumerations and records (#2170)

* Fix for detector `UncallableMethodOfAnonymousClass` to not report unused methods of method-local enumerations and records

During compilation, enumerations and records are turned into Java classes with some auto-generated methods. Some of these methods are called by the code but some of them not. However, this is not a programming error or bad practice, these methods must not be considered as dead code because their generation cannot be prevented. Therefore no bug report `UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS` must be issued to such classes even if they are defined inside a method. See issue ([#2120](#2120))

* Fix the test case

* Solution changed to only disregard auto-generated methods of enums and records

Co-authored-by: Kengo TODA <skypencil@gmail.com>
  • Loading branch information
baloghadamsoftware and KengoTODA committed Oct 11, 2022
1 parent 96d50b5 commit 119956b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Currently the versioning policy of this project follows [Semantic Versioning v2.
- Fixed detector `DontUseFloatsAsLoopCounters` to prevent false positives. ([#2126](https://github.com/spotbugs/spotbugs/issues/2126))
- Fixed regression in `4.7.2` caused by ([#2141](https://github.com/spotbugs/spotbugs/pull/2141))
- improve compatibility with later version of jdk (>= 13). ([#2188](https://github.com/spotbugs/spotbugs/issues/2188))
- Fixed detector `UncallableMethodOfAnonymousClass` to not report unused methods of method-local enumerations and records ([#2120](https://github.com/spotbugs/spotbugs/issues/2120))
- Fixed detector `FindSqlInjection` to detect bug `SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE SQL` with high priority in case of unsafe appends also in Java 11 and above ([#2183](https://github.com/spotbugs/spotbugs/issues/2183))
- Fixed detector `StringConcatenation` to detect bug `SBSC_USE_STRINGBUFFER_CONCATENATION` also in Java 11 and above ([#2182](https://github.com/spotbugs/spotbugs/issues/2182))
- Fixed `OpcodeStackDetector` to to handle propagation of taints properly in case of string concatenation in Java 9 and above ([#2183](https://github.com/spotbugs/spotbugs/issues/2183))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package edu.umd.cs.findbugs.detect;

import org.junit.Before;
import org.junit.Test;

import edu.umd.cs.findbugs.AbstractIntegrationTest;
import edu.umd.cs.findbugs.test.matcher.BugInstanceMatcher;
import edu.umd.cs.findbugs.test.matcher.BugInstanceMatcherBuilder;

import static edu.umd.cs.findbugs.test.CountMatcher.containsExactly;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeThat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo;

public class Issue2120Test extends AbstractIntegrationTest {
@Before
public void verifyJavaVersion() {
assumeFalse(System.getProperty("java.specification.version").startsWith("1."));
int javaVersion = Integer.parseInt(System.getProperty("java.specification.version"));
assumeThat(javaVersion, is(greaterThanOrEqualTo(11)));
}

@Test
public void test() {
performAnalysis("../java14/Issue2120.class",
"../java14/Issue2120$1MyEnum.class",
"../java14/Issue2120$1MyRecord.class");
BugInstanceMatcher matcher = new BugInstanceMatcherBuilder()
.bugType("UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS").build();
assertThat(getBugCollection(), containsExactly(0, matcher));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package edu.umd.cs.findbugs.detect;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

Expand Down Expand Up @@ -156,7 +157,18 @@ private boolean skip(Method obj) {
if (obj.isAbstract()) {
return true;
}

if (Values.SLASHED_JAVA_LANG_ENUM.equals(getSuperclassName()) &&
(("values".equals(obj.getName()) &&
("()[L" + getClassName() + ";").equals(obj.getSignature())) ||
("valueOf".equals(obj.getName())) &&
("(Ljava/lang/String;)L" + getClassName() + ";").equals(obj.getSignature()))) {
return true;
}
if (Values.SLASHED_JAVA_LANG_RECORD.equals(getSuperclassName()) &&
(Arrays.stream(getThisClass().getFields()).anyMatch(f -> f.getName().equals(obj.getName()))) &&
(obj.getSignature().startsWith("()"))) {
return true;
}
String methodName = obj.getName();
String sig = obj.getSignature();
if (Const.CONSTRUCTOR_NAME.equals(methodName)) {
Expand All @@ -165,6 +177,7 @@ private boolean skip(Method obj) {
if (Const.STATIC_INITIALIZER_NAME.equals(methodName)) {
return true;
}

if ("()Ljava/lang/Object;".equals(sig) && ("readResolve".equals(methodName) || "writeReplace".equals(methodName))) {
return true;
}
Expand Down
4 changes: 4 additions & 0 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/util/Values.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ public final class Values {
@SlashedClassName
public static final String SLASHED_JAVA_LANG_BOOLEAN = "java/lang/Boolean";
@SlashedClassName
public static final String SLASHED_JAVA_LANG_ENUM = "java/lang/Enum";
@SlashedClassName
public static final String SLASHED_JAVA_LANG_RECORD = "java/lang/Record";
@SlashedClassName
public static final String SLASHED_JAVA_UTIL_COMPARATOR = "java/util/Comparator";
@SlashedClassName
public static final String SLASHED_JAVA_UTIL_COLLECTION = "java/util/Collection";
Expand Down
12 changes: 12 additions & 0 deletions spotbugsTestCases/src/java14/Issue2120.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
public class Issue2120 {
static void method() {
record MyRecord(int from, int to) { /**/ }

enum MyEnum {
RED, BLUE;
}

System.out.println(new MyRecord(1, 2));
System.out.println(MyEnum.RED);
}
}

0 comments on commit 119956b

Please sign in to comment.