### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java,v retrieving revision 1.183 diff -u -r1.183 ClassScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 1 Nov 2010 14:15:47 -0000 1.183 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 19 Apr 2011 14:49:52 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -148,6 +149,9 @@ buildMethods(); SourceTypeBinding sourceType = this.referenceContext.binding; + if (!sourceType.isPrivate() && sourceType.superclass instanceof SourceTypeBinding && sourceType.superclass.isPrivate()) + ((SourceTypeBinding) sourceType.superclass).tagIndirectlyAccessibleMembers(); + if (sourceType.isMemberType() && !sourceType.isLocalType()) ((MemberTypeBinding) sourceType).checkSyntheticArgsAndFields(); Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java,v retrieving revision 1.9 diff -u -r1.9 ExtraCompilerModifiers.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java 7 Mar 2009 01:08:09 -0000 1.9 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java 19 Apr 2011 14:49:52 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -31,7 +32,10 @@ final int AccUnresolved = ASTNode.Bit26; final int AccBlankFinal = ASTNode.Bit27; // for blank final variables final int AccIsDefaultConstructor = ASTNode.Bit27; // for default constructor - final int AccLocallyUsed = ASTNode.Bit28; // used to diagnose unused private/local members + final int AccLocallyUsed = ASTNode.Bit28; // used to diagnose unused (a) private/local members or (b) members of private classes + // generally set when actual usage has been detected + // or, (b) when member of a private class is exposed via a non-private subclass + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281 final int AccVisibilityMASK = ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate; final int AccOverriding = ASTNode.Bit29; // record fact a method overrides another one Index: compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java,v retrieving revision 1.188 diff -u -r1.188 SourceTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 15 Mar 2011 11:33:27 -0000 1.188 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 19 Apr 2011 14:49:55 -0000 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -1680,4 +1681,19 @@ public FieldBinding[] unResolvedFields() { return this.fields; } + +public void tagIndirectlyAccessibleMembers() { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281 + for (int i = 0; i < this.fields.length; i++) { + if (!this.fields[i].isPrivate()) + this.fields[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed; + } + for (int i = 0; i < this.memberTypes.length; i++) { + if (!this.memberTypes[i].isPrivate()) + this.memberTypes[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed; + } + if (this.superclass.isPrivate()) + if (this.superclass instanceof SourceTypeBinding) // should always be true because private super type can only be accessed in same CU + ((SourceTypeBinding) this.superclass).tagIndirectlyAccessibleMembers(); +} } #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java,v retrieving revision 1.42 diff -u -r1.42 ProblemTypeAndMethodTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java 4 Feb 2011 08:21:17 -0000 1.42 +++ src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java 19 Apr 2011 14:50:08 -0000 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -5154,6 +5155,152 @@ "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660 +// check independence of textual order +public void test099a() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public class C extends B {\n" + + " public void foo(int a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(double a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(boolean a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(byte a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " }\n" + + " private class B extends A {\n" + + " public void foo(int a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(float a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(double a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(char a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " }\n" + + " private class A {\n" + + " public void foo(int a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(float a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(boolean a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(Integer a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 2)\n" + + " public class C extends B {\n" + + " ^\n" + + "Access to enclosing constructor X.B() is emulated by a synthetic accessor method\n" + + "----------\n" + + "2. WARNING in X.java (at line 16)\n" + + " private class B extends A {\n" + + " ^\n" + + "Access to enclosing constructor X.A() is emulated by a synthetic accessor method\n" + + "----------\n" + + "3. WARNING in X.java (at line 23)\n" + + " public void foo(double a) {\n" + + " ^^^^^^^^^^^^^\n" + + "The method foo(double) from the type X.B is never used locally\n" + + "----------\n" + + "4. WARNING in X.java (at line 31)\n" + + " public void foo(int a) {\n" + + " ^^^^^^^^^^\n" + + "The method foo(int) from the type X.A is never used locally\n" + + "----------\n" + + "5. WARNING in X.java (at line 34)\n" + + " public void foo(float a) {\n" + + " ^^^^^^^^^^^^\n" + + "The method foo(float) from the type X.A is never used locally\n" + + "----------\n" + + "6. WARNING in X.java (at line 37)\n" + + " public void foo(boolean a) {\n" + + " ^^^^^^^^^^^^^^\n" + + "The method foo(boolean) from the type X.A is never used locally\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660 +// check usage via super-call +public void test099b() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " private class A {\n" + + " public void foo(int a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(float a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(boolean a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(Integer a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " }\n" + + " private class B extends A {\n" + + " public void foo(int a) {\n" + + " super.foo(a);\n" + + " }\n" + + " public void foo(float a) {\n" + + " super.foo(a);\n" + + " }\n" + + " public void foo(double a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(char a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " }\n" + + " public class C extends B {\n" + + " public void foo(int a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " public void foo(double a) {\n" + + " super.foo(a);\n" + + " }\n" + + " public void foo(boolean a) {\n" + + " super.foo(a);\n" + + " }\n" + + " public void foo(byte a) {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 16)\n" + + " private class B extends A {\n" + + " ^\n" + + "Access to enclosing constructor X.A() is emulated by a synthetic accessor method\n" + + "----------\n" + + "2. WARNING in X.java (at line 30)\n" + + " public class C extends B {\n" + + " ^\n" + + "Access to enclosing constructor X.B() is emulated by a synthetic accessor method\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660 public void test100() { this.runNegativeTest( new String[] { Index: src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java,v retrieving revision 1.32 diff -u -r1.32 ProgrammingProblemsTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java 8 Mar 2011 16:41:35 -0000 1.32 +++ src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java 19 Apr 2011 14:50:10 -0000 @@ -7,7 +7,9 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Stephan Herrmann - Contribution for bug 185682 - Increment/decrement operators mark local variables as read + * Stephan Herrmann - Contributions for + * bug 185682 - Increment/decrement operators mark local variables as read + * bug 328281 - visibility leaks not detected when analyzing unused field in private class *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -36,7 +38,7 @@ // Only the highest compliance level is run; add the VM argument // -Dcompliance=1.4 (for example) to lower it if needed static { -// TESTS_NAMES = new String[] { "test0055" }; +// TESTS_NAMES = new String[] { "test0052" }; // TESTS_NUMBERS = new int[] { 56 }; // TESTS_RANGE = new int[] { 1, -1 }; } @@ -2125,6 +2127,79 @@ true/*shouldFlushOutputDirectory*/, customOptions); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281 +public void test0052() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "class X {\n" + + " Y y = new Y();\n" + + " private class Y {\n" + + " int abc;\n" + + " Y() {\n" + + " abc++;\n" + // not a relevant usage + " }\n" + + " }\n" + + " class Z extends Y {}\n" + // makes 'abc' externally accessible + "}" + }, + "", + null/*classLibraries*/, + true/*shouldFlushOutputDirectory*/, + null/*vmArguments*/, + customOptions, + null/*requestor*/); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281 +// multi-level inheritance +public void test0052a() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE); + this.runConformTest( + new String[] { + "Outer.java", + "class Outer {\n" + + " private class Inner1 {\n" + + " int foo;\n" + + " }\n" + + " private class Inner2 extends Inner1 { }\n" + + " class Inner3 extends Inner2 { }\n" + // foo is exposed here + "}\n" + }, + "", + null/*classLibraries*/, + true/*shouldFlushOutputDirectory*/, + null/*vmArguments*/, + customOptions, + null/*requestor*/); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281 +// member type of private +public void test0052b() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE); + this.runConformTest( + new String[] { + "Outer.java", + "class Outer {\n" + + " private class Inner1 {\n" + + " class Foo{}\n" + + " }\n" + + " private class Inner2 extends Inner1 { }\n" + + " class Inner3 extends Inner2 { }\n" + // Foo is exposed here + "}\n" + }, + "", + null/*classLibraries*/, + true/*shouldFlushOutputDirectory*/, + null/*vmArguments*/, + customOptions, + null/*requestor*/); +} // https://bugs.eclipse.org/bugs/show_bug.cgi?id=328519 public void test0053() throws Exception { Map customOptions = getCompilerOptions();