diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e93a6d19bd..dc2067bc13a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Currently the versioning policy of this project follows [Semantic Versioning v2. - Fix FP in CT_CONSTRUCTOR_THROW when the finalizer does not run, since the exception is thrown before java.lang.Object's constructor exits for checked exceptions ([#2710](https://github.com/spotbugs/spotbugs/issues/2710)) - Applied changes for bcel 6.8.0 with adjustments to constant pool ([#2756](https://github.com/spotbugs/spotbugs/pull/2756)) - More information bcel changes can be found on ([#2757](https://github.com/spotbugs/spotbugs/pull/2757)) +- Fix FN in CT_CONSTRUCTOR_THROW when the return value of the called method is not void or primitive type. ### Changed - Improved Matcher checks for empty strings ([#2755](https://github.com/spotbugs/spotbugs/pull/2755)) diff --git a/spotbugs-tests/src/test/java/edu/umd/cs/findbugs/detect/ConstructorThrowTest.java b/spotbugs-tests/src/test/java/edu/umd/cs/findbugs/detect/ConstructorThrowTest.java index 305b886f949..8b2991a6231 100644 --- a/spotbugs-tests/src/test/java/edu/umd/cs/findbugs/detect/ConstructorThrowTest.java +++ b/spotbugs-tests/src/test/java/edu/umd/cs/findbugs/detect/ConstructorThrowTest.java @@ -152,6 +152,20 @@ void testConstructorThrowCheck20() { assertCTBugInLine(13); } + @Test + void testConstructorThrowCheck21() { + performAnalysis("constructorthrow/ConstructorThrowTest21.class"); + assertNumOfCTBugs(1); + assertCTBugInLine(9); + } + + @Test + void testConstructorThrowCheck22() { + performAnalysis("constructorthrow/ConstructorThrowTest22.class"); + assertNumOfCTBugs(1); + assertCTBugInLine(11); + } + @Test void testGoodConstructorThrowCheck1() { performAnalysis("constructorthrow/ConstructorThrowNegativeTest1.class"); @@ -255,6 +269,12 @@ void testGoodConstructorThrowCheck17() { assertNumOfCTBugs(0); } + @Test + void testGoodConstructorThrowCheck18() { + performAnalysis("constructorthrow/ConstructorThrowNegativeTest18.class"); + assertNumOfCTBugs(0); + } + private void assertNumOfCTBugs(int num) { final BugInstanceMatcher bugTypeMatcher = new BugInstanceMatcherBuilder() .bugType("CT_CONSTRUCTOR_THROW").build(); diff --git a/spotbugs/src/main/java/edu/umd/cs/findbugs/detect/ConstructorThrow.java b/spotbugs/src/main/java/edu/umd/cs/findbugs/detect/ConstructorThrow.java index 5afd71ce35d..b50f4ebd1ce 100644 --- a/spotbugs/src/main/java/edu/umd/cs/findbugs/detect/ConstructorThrow.java +++ b/spotbugs/src/main/java/edu/umd/cs/findbugs/detect/ConstructorThrow.java @@ -375,7 +375,7 @@ private String getCalledMethodFQN(int seen) { } } else { return String.format("%s.%s : %s", getDottedClassConstantOperand(), getNameConstantOperand(), - getSigConstantOperand()); + toDotted(getSigConstantOperand())); } return ""; } diff --git a/spotbugsTestCases/src/java/constructorthrow/ConstructorThrowTest21.java b/spotbugsTestCases/src/java/constructorthrow/ConstructorThrowTest21.java new file mode 100644 index 00000000000..1941d5c9c7b --- /dev/null +++ b/spotbugsTestCases/src/java/constructorthrow/ConstructorThrowTest21.java @@ -0,0 +1,15 @@ +package constructorthrow; + +/** + * Calling a static function with not void or primitive return value from the constructor, + * which throws an unchecked exception. + */ +public class ConstructorThrowTest21 { + public ConstructorThrowTest21() { + ConstructorThrowTest21.test(); + } + + private static String test() { + throw new IllegalStateException(); + } +} diff --git a/spotbugsTestCases/src/java/constructorthrow/ConstructorThrowTest22.java b/spotbugsTestCases/src/java/constructorthrow/ConstructorThrowTest22.java new file mode 100644 index 00000000000..5be81aab19d --- /dev/null +++ b/spotbugsTestCases/src/java/constructorthrow/ConstructorThrowTest22.java @@ -0,0 +1,17 @@ +package constructorthrow; + +import java.io.IOException; + +/** + * Calling a static function with not void or primitive return value from the constructor, + * which throws a checked exception. + */ +public class ConstructorThrowTest22 { + public ConstructorThrowTest22() throws IOException { + ConstructorThrowTest22.test(); + } + + private static String test() throws IOException { + throw new IOException(); + } +}