diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedArrayReadWriteInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedArrayReadWriteInspection.java index 918a5c30ed12..900871790a9d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedArrayReadWriteInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MismatchedArrayReadWriteInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.CloneUtils; import com.siyeh.ig.psiutils.VariableAccessUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -137,8 +138,7 @@ public class MismatchedArrayReadWriteInspection extends BaseInspection { if (VariableAccessUtils.arrayContentsAreAssigned(variable, context)) { return true; } - final PsiExpression initializer = variable.getInitializer(); - if (initializer != null && !isDefaultArrayInitializer(initializer)) { + if (!isDefaultArrayInitializer(variable.getInitializer())) { return true; } return variableIsWritten(variable, context); @@ -149,11 +149,39 @@ public class MismatchedArrayReadWriteInspection extends BaseInspection { if (VariableAccessUtils.arrayContentsAreAccessed(variable, context)) { return true; } + if (isPossiblyReferenceThatIsReadLater(variable.getInitializer())) { + return true; + } return variableIsRead(variable, context); } - private static boolean isDefaultArrayInitializer( - PsiExpression initializer) { + private static boolean isPossiblyReferenceThatIsReadLater(PsiExpression initializer) { + if (initializer == null || initializer instanceof PsiNewExpression || initializer instanceof PsiArrayInitializerExpression) { + return false; + } + if (initializer instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)initializer; + final PsiMethod method = methodCallExpression.resolveMethod(); + if (method == null) { + return true; + } + if (CloneUtils.isClone(method)) { + return false; + } + @NonNls final String name = method.getName(); + if (!"copyOf".equals(name) && !"copyOfRange".equals(name)) { + return true; + } + final PsiClass aClass = method.getContainingClass(); + return aClass == null || !CommonClassNames.JAVA_UTIL_ARRAYS.equals(aClass.getQualifiedName()); + } + return true; + } + + private static boolean isDefaultArrayInitializer(PsiExpression initializer) { + if (initializer == null) { + return true; + } if (initializer instanceof PsiNewExpression) { final PsiNewExpression newExpression = (PsiNewExpression)initializer; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/mismatched_array_read_write/MismatchedArrayReadWrite.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/mismatched_array_read_write/MismatchedArrayReadWrite.java index 7594b6e91756..8175fcc730a4 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/mismatched_array_read_write/MismatchedArrayReadWrite.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/mismatched_array_read_write/MismatchedArrayReadWrite.java @@ -117,3 +117,65 @@ class Test{ return null; } } +class Bug { + // Example 1 + public void test1() { + final java.util.List results = new java.util.ArrayList<>(); + for (int i = 0; i < 10; i++) { + results.add(new long[3]); + } + + for (int i = 0; i < results.size(); i++) { + final long[] longs = results.get(i); // <-- Contents of array 'longs' are written to, but never read + for (int j = 0; j < 3; j++) { + longs[j] = i * j; + } + } + + for (long[] result : results) { + for (long l : result) { + System.out.println(l); + } + } + } + + // Example 2 + private int[] _ints = {0}; + + public void print() { + for (int i : _ints) { + System.out.println(i); + } + } + + public void test2() { + final Bug bug = new Bug(); + final int[] ints = bug._ints; // <-- Contents of array 'ints' are written to, but never read + ints[0] = 1; + bug.print(); + } +} +class Toster +{ + private static final int MAX = 1; + + public static void main(String[] args) + { + new Toster().run(); + } + + private int[][] values = new int[][] { {new java.util.Random().nextInt()}, {new java.util.Random().nextInt()} }; + + private void run() + { + for (int j = new java.util.Random().nextInt(values.length); j < new java.util.Random().nextInt(values.length); j++) + { + int[] array = values[j]; //IDEA says here: contents of array 'array' are written to, but never used + + for (int i = 0; i < MAX; i++) + { + array[i] = new java.util.Random().nextInt(); + } + } + } +} \ No newline at end of file