Skip to content

Commit c928f51

Browse files
committed
Fix isAtomicField method arg type
1 parent 66095db commit c928f51

File tree

4 files changed

+78
-94
lines changed

4 files changed

+78
-94
lines changed

spotbugs-tests/src/test/java/edu/umd/cs/findbugs/detect/AtomicOperationsCombinedDetectorTest.java

+67-89
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@
22

33
import org.junit.jupiter.api.Test;
44
import edu.umd.cs.findbugs.AbstractIntegrationTest;
5-
import edu.umd.cs.findbugs.test.matcher.BugInstanceMatcher;
6-
import edu.umd.cs.findbugs.test.matcher.BugInstanceMatcherBuilder;
7-
8-
import static edu.umd.cs.findbugs.test.CountMatcher.containsExactly;
9-
import static org.hamcrest.MatcherAssert.assertThat;
10-
import static org.hamcrest.Matchers.hasItem;
115

126
class AtomicOperationsCombinedDetectorTest extends AbstractIntegrationTest {
137

14-
public static final String OPERATIONS_ARE_NOT_ATOMIC = "AT_COMBINED_ATOMIC_OPERATIONS_ARE_NOT_ATOMIC";
15-
public static final String NEEDS_SYNCHRONIZATION = "AT_ATOMIC_OPERATION_NEEDS_SYNCHRONIZATION";
8+
private static final String OPERATIONS_ARE_NOT_ATOMIC = "AT_COMBINED_ATOMIC_OPERATIONS_ARE_NOT_ATOMIC";
9+
private static final String NEEDS_SYNCHRONIZATION = "AT_ATOMIC_OPERATION_NEEDS_SYNCHRONIZATION";
1610

1711
@Test
1812
void testSafeSynchronizedList() {
@@ -31,26 +25,26 @@ void testSafeSynchronizedList() {
3125
@Test
3226
void testUnsafeSynchronizedList() {
3327
performAnalysis("atomicMethods/UnsafeSynchronizedList.class");
34-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
35-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
36-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedList", "addAndPrintNumbers", 13);
28+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
29+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
30+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedList", "addAndPrintNumbers", 13);
3731
}
3832

3933
@Test
4034
void testUnsafeSynchronizedListWithMultipleSync() {
4135
performAnalysis("atomicMethods/UnsafeSynchronizedListWithMultipleSync.class");
42-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
43-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
44-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListWithMultipleSync", "addAndPrintNumbers", 32);
36+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
37+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
38+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListWithMultipleSync", "addAndPrintNumbers", 32);
4539
}
4640

4741
@Test
4842
void testUnsafeSynchronizedListWithMethodInit() {
4943
performAnalysis("atomicMethods/UnsafeSynchronizedListWithMethodInit.class");
50-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 1);
51-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
52-
assertBug(NEEDS_SYNCHRONIZATION, "UnsafeSynchronizedListWithMethodInit", "init", 12);
53-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListWithMethodInit", "addAndPrintNumbers", 17);
44+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 1);
45+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
46+
assertBugInMethodAtLine(NEEDS_SYNCHRONIZATION, "UnsafeSynchronizedListWithMethodInit", "init", 12);
47+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListWithMethodInit", "addAndPrintNumbers", 17);
5448
}
5549

5650
@Test
@@ -68,19 +62,19 @@ void testUnsafeSynchronizedSet() {
6862
"atomicMethods/UnsafeSynchronizedSet.class",
6963
"atomicMethods/UnsafeSynchronizedSortedSet.class",
7064
"atomicMethods/UnsafeSynchronizedNavigableSet.class");
71-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 3);
72-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
73-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSet", "addAndPrintNumbers", 13);
74-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSortedSet", "addAndPrintNumbers", 12);
75-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedNavigableSet", "addAndPrintNumbers", 12);
65+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 3);
66+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
67+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSet", "addAndPrintNumbers", 13);
68+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSortedSet", "addAndPrintNumbers", 12);
69+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedNavigableSet", "addAndPrintNumbers", 12);
7670
}
7771

7872
@Test
7973
void testUnsafeSynchronizedCollection() {
8074
performAnalysis("atomicMethods/UnsafeSynchronizedCollection.class");
81-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
82-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
83-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedCollection", "addAndPrintNumbers", 12);
75+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
76+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
77+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedCollection", "addAndPrintNumbers", 12);
8478
}
8579

8680
@Test
@@ -89,11 +83,11 @@ void testUnsafeSynchronizedMap() {
8983
"atomicMethods/UnsafeSynchronizedMap.class",
9084
"atomicMethods/UnsafeSynchronizedNavigableMap.class",
9185
"atomicMethods/UnsafeSynchronizedSortedMap.class");
92-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 3);
93-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
94-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedMap", "addAndPrintNumbers", 13);
95-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedNavigableMap", "addAndPrintNumbers", 12);
96-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSortedMap", "addAndPrintNumbers", 12);
86+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 3);
87+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
88+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedMap", "addAndPrintNumbers", 13);
89+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedNavigableMap", "addAndPrintNumbers", 12);
90+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSortedMap", "addAndPrintNumbers", 12);
9791
}
9892

9993
@Test
@@ -108,36 +102,36 @@ void testSynchronizedListInSynchronizedMethod() {
108102
@Test
109103
void testUnsafeSynchronizedListAndSet() {
110104
performAnalysis("atomicMethods/UnsafeSynchronizedListAndSet.class");
111-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 2);
112-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
113-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListAndSet", "addAndPrintNumbers", 16);
114-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListAndSet", "addAndPrintNumbers", 20);
105+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 2);
106+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
107+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListAndSet", "addAndPrintNumbers", 16);
108+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListAndSet", "addAndPrintNumbers", 20);
115109
}
116110

117111
@Test
118112
void testPartialSynchronizedListAndSet() {
119113
performAnalysis("atomicMethods/PartialSynchronizedListAndSet.class", "atomicMethods/PartialSynchronizedListAndSet2.class");
120-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 2);
121-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
122-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "PartialSynchronizedListAndSet", "addAndPrintNumbers", 16);
123-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "PartialSynchronizedListAndSet2", "addAndPrintNumbers", 22);
114+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 2);
115+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
116+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "PartialSynchronizedListAndSet", "addAndPrintNumbers", 16);
117+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "PartialSynchronizedListAndSet2", "addAndPrintNumbers", 22);
124118
}
125119

126120
@Test
127121
void testUnsafeSynchronizedListWithPrivateMethods() {
128122
performAnalysis("atomicMethods/UnsafeSynchronizedListWithPrivateMethods.class");
129-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
130-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
131-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListWithPrivateMethods", "addAndPrintNumbers", 13);
123+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
124+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
125+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedListWithPrivateMethods", "addAndPrintNumbers", 13);
132126
}
133127

134128
@Test
135129
void testUnsafeSynchronizedSetInMultipleMethods() {
136130
performAnalysis("atomicMethods/UnsafeSynchronizedSetInMultipleMethods.class");
137-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 2);
138-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
139-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSetInMultipleMethods", "addAndPrintNumbers", 13);
140-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSetInMultipleMethods", "removeAndPrintNumbers", 19);
131+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 2);
132+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
133+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSetInMultipleMethods", "addAndPrintNumbers", 13);
134+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedSetInMultipleMethods", "removeAndPrintNumbers", 19);
141135
}
142136

143137
@Test
@@ -149,10 +143,10 @@ void testSafeSynchronizedMapIncrement() {
149143
@Test
150144
void testUnsafeSynchronizedMapIncrement() {
151145
performAnalysis("atomicMethods/UnsafeSynchronizedMapIncrement.class");
152-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
153-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 1);
154-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedMapIncrement", "increment", 17);
155-
assertBug(NEEDS_SYNCHRONIZATION, "UnsafeSynchronizedMapIncrement", "getCount", 21);
146+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
147+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 1);
148+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeSynchronizedMapIncrement", "increment", 17);
149+
assertBugInMethodAtLine(NEEDS_SYNCHRONIZATION, "UnsafeSynchronizedMapIncrement", "getCount", 21);
156150
}
157151

158152
@Test
@@ -170,29 +164,29 @@ void testUnsafeAtomicReference() {
170164
"atomicMethods/UnsafeAtomicReference4.class",
171165
"atomicMethods/UnsafeAtomicReference4$Inner.class",
172166
"atomicMethods/UnsafeAtomicReference5.class");
173-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 11);
174-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 3);
175-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference", "update", 17);
176-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference", "add", 22);
177-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger", 18);
178-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger", 18);
179-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger2", 26);
180-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger2", 26);
181-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference3", "preparation", 11);
182-
assertBug(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReference3", "run", 15);
183-
assertBug(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReference3", "after", 19);
184-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference4", "initProcessing", 22);
185-
assertBug(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReference4", "finishProcessing", 33);
186-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference5", "lambda$incrementAtomicInteger$0", 15);
167+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 11);
168+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 3);
169+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference", "update", 17);
170+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference", "add", 22);
171+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger", 18);
172+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger", 18);
173+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger2", 26);
174+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference2", "incrementAtomicInteger2", 26);
175+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference3", "preparation", 11);
176+
assertBugInMethodAtLine(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReference3", "run", 15);
177+
assertBugInMethodAtLine(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReference3", "after", 19);
178+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference4", "initProcessing", 22);
179+
assertBugInMethodAtLine(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReference4", "finishProcessing", 33);
180+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReference5", "lambda$incrementAtomicInteger$0", 15);
187181
}
188182

189183
@Test
190184
void testUnsafeAtomicReferenceValueSet() {
191185
performAnalysis("atomicMethods/UnsafeAtomicReferenceValueSet.class");
192-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 1);
193-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
194-
assertBug(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReferenceValueSet", "init", 10);
195-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReferenceValueSet", "update", 15);
186+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 1);
187+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
188+
assertBugInMethodAtLine(NEEDS_SYNCHRONIZATION, "UnsafeAtomicReferenceValueSet", "init", 10);
189+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeAtomicReferenceValueSet", "update", 15);
196190
}
197191

198192
@Test
@@ -204,9 +198,9 @@ void testSafeLocalAtomicInteger() {
204198
@Test
205199
void testUnsafeLocalAtomicInteger() {
206200
performAnalysis("atomicMethods/UnsafeLocalAtomicInteger.class");
207-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 1);
208-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
209-
assertBug(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeLocalAtomicInteger", "increment", 23);
201+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 1);
202+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
203+
assertBugInMethodAtLine(OPERATIONS_ARE_NOT_ATOMIC, "UnsafeLocalAtomicInteger", "increment", 23);
210204
}
211205

212206
@Test
@@ -234,23 +228,7 @@ void testSafeAtomicCallsWithLambda() {
234228
}
235229

236230
private void assertZeroBugs() {
237-
assertNumOfBugs(OPERATIONS_ARE_NOT_ATOMIC, 0);
238-
assertNumOfBugs(NEEDS_SYNCHRONIZATION, 0);
239-
}
240-
241-
private void assertNumOfBugs(String bugType, int num) {
242-
final BugInstanceMatcher bugTypeMatcher = new BugInstanceMatcherBuilder()
243-
.bugType(bugType).build();
244-
assertThat(getBugCollection(), containsExactly(num, bugTypeMatcher));
245-
}
246-
247-
private void assertBug(String bugType, String className, String methodName, int line) {
248-
final BugInstanceMatcher bugInstanceMatcher = new BugInstanceMatcherBuilder()
249-
.bugType(bugType)
250-
.inClass(className)
251-
.inMethod(methodName)
252-
.atLine(line)
253-
.build();
254-
assertThat(getBugCollection(), hasItem(bugInstanceMatcher));
231+
assertBugTypeCount(OPERATIONS_ARE_NOT_ATOMIC, 0);
232+
assertBugTypeCount(NEEDS_SYNCHRONIZATION, 0);
255233
}
256234
}

spotbugs/src/main/java/edu/umd/cs/findbugs/detect/AtomicOperationsCombinedDetector.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import edu.umd.cs.findbugs.ba.CFG;
5151
import edu.umd.cs.findbugs.ba.CFGBuilderException;
5252
import edu.umd.cs.findbugs.ba.ClassContext;
53-
import edu.umd.cs.findbugs.ba.ClassMember;
5453
import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
5554
import edu.umd.cs.findbugs.ba.Location;
5655
import edu.umd.cs.findbugs.ba.OpcodeStackScanner;
@@ -152,12 +151,12 @@ private void collectFieldsForAtomicityCheck(ClassContext classContext, Method me
152151
}
153152
}
154153

155-
private static boolean isAtomicField(ClassMember classMember) {
156-
if (classMember == null) {
154+
private static boolean isAtomicField(XMethod xMethod) {
155+
if (xMethod == null) {
157156
return false;
158157
}
159-
return CollectionAnalysis.isSynchronizedCollection(classMember)
160-
|| (classMember.getClassName().startsWith("java.util.concurrent.atomic") && classMember.getSignature().endsWith(")V"));
158+
return CollectionAnalysis.isSynchronizedCollection(xMethod)
159+
|| (xMethod.getClassName().startsWith("java.util.concurrent.atomic") && xMethod.getSignature().endsWith(")V"));
161160
}
162161

163162
private void analyzeFieldsForAtomicityViolations(ClassContext classContext, Method method) throws CheckedAnalysisException {

spotbugs/src/main/java/edu/umd/cs/findbugs/util/CollectionAnalysis.java

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
*/
3030
public final class CollectionAnalysis {
3131

32+
/**
33+
* Private constructor to prevent instantiation, because it is a utility class.
34+
*/
3235
private CollectionAnalysis() {
3336
}
3437

spotbugs/src/main/java/edu/umd/cs/findbugs/util/MethodAnalysis.java

+4
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@
2828
*/
2929
public final class MethodAnalysis {
3030

31+
/**
32+
* Private constructor to prevent instantiation, because it is a utility class.
33+
*/
3134
private MethodAnalysis() {
3235
}
3336

3437
/**
3538
* Check if the location is duplicated in the method.
39+
* Locations in finally blocks will be duplicated in the bytecode level.
3640
*
3741
* @return {@code true} if the location is duplicated in the method, {@code false} otherwise
3842
* @throws CheckedAnalysisException if an error occurs during the analysis

0 commit comments

Comments
 (0)