View | Details | Raw Unified | Return to bug 328281 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java (+5 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 146-151 Link Here
146
	void buildFieldsAndMethods() {
147
	void buildFieldsAndMethods() {
147
		buildFields();
148
		buildFields();
148
		buildMethods();
149
		buildMethods();
150
		if ((this.referenceContext.binding.tagBits & TagBits.IsAccessibleViaNonPrivateSub) != 0)
151
			this.referenceContext.binding.tagIndirectlyAccessibleFields();
149
152
150
		SourceTypeBinding sourceType = this.referenceContext.binding;
153
		SourceTypeBinding sourceType = this.referenceContext.binding;
151
		if (sourceType.isMemberType() && !sourceType.isLocalType())
154
		if (sourceType.isMemberType() && !sourceType.isLocalType())
Lines 903-908 Link Here
903
			} else {
906
			} else {
904
				// only want to reach here when no errors are reported
907
				// only want to reach here when no errors are reported
905
				sourceType.superclass = superclass;
908
				sourceType.superclass = superclass;
909
				if (superclass.isPrivate() && !sourceType.isPrivate())
910
					superclass.tagBits |= TagBits.IsAccessibleViaNonPrivateSub;
906
				return true;
911
				return true;
907
			}
912
			}
908
		}
913
		}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java (-1 / +5 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
11
 *     						bug 185682 - Increment/decrement operators mark local variables as read
12
 *     						bug 328281 - visibility leaks not detected when analyzing unused field in private class
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
14
package org.eclipse.jdt.internal.compiler.lookup;
13
15
Lines 299-304 Link Here
299
public final boolean isOrEnclosedByPrivateType() {
301
public final boolean isOrEnclosedByPrivateType() {
300
	if ((this.modifiers & ClassFileConstants.AccPrivate) != 0)
302
	if ((this.modifiers & ClassFileConstants.AccPrivate) != 0)
301
		return true;
303
		return true;
304
	if ((this.tagBits & TagBits.IsAccessibleViaNonPrivateSub) != 0)
305
		return false; // visibility leak through non-private subclass
302
	return this.declaringClass != null && this.declaringClass.isOrEnclosedByPrivateType();
306
	return this.declaringClass != null && this.declaringClass.isOrEnclosedByPrivateType();
303
}
307
}
304
/* Answer true if the receiver has private visibility and is used locally
308
/* Answer true if the receiver has private visibility and is used locally
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java (+3 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 705-710 Link Here
705
public final boolean isOrEnclosedByPrivateType() {
706
public final boolean isOrEnclosedByPrivateType() {
706
	if ((this.modifiers & ClassFileConstants.AccPrivate) != 0)
707
	if ((this.modifiers & ClassFileConstants.AccPrivate) != 0)
707
		return true;
708
		return true;
709
	if ((this.tagBits & TagBits.IsAccessibleViaNonPrivateSub) != 0)
710
		return false; // visibility leak through non-private subclass
708
	return this.declaringClass != null && this.declaringClass.isOrEnclosedByPrivateType();
711
	return this.declaringClass != null && this.declaringClass.isOrEnclosedByPrivateType();
709
}
712
}
710
713
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (-2 / +3 lines)
Lines 8-13 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
11
 *******************************************************************************/
12
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
13
package org.eclipse.jdt.internal.compiler.lookup;
13
14
Lines 456-462 Link Here
456
		if (current == null && !isOrEnclosedByPrivateType) {
457
		if (current == null && !isOrEnclosedByPrivateType) {
457
			int length = inherited.length;
458
			int length = inherited.length;
458
			for (int i = 0; i < length; i++){
459
			for (int i = 0; i < length; i++){
459
				inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
460
				inherited[i].original().tagBits |= TagBits.IsAccessibleViaNonPrivateSub;
460
			}
461
			}
461
		}
462
		}
462
463
Lines 496-502 Link Here
496
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed,
497
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed,
497
			// inherited methods of super classes are too. current == null case handled already.
498
			// inherited methods of super classes are too. current == null case handled already.
498
			if (!isOrEnclosedByPrivateType && current != null) {
499
			if (!isOrEnclosedByPrivateType && current != null) {
499
				inheritedMethod.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
500
				inheritedMethod.original().tagBits |= TagBits.IsAccessibleViaNonPrivateSub;
500
			}
501
			}
501
			matchingInherited[++index] = inheritedMethod;
502
			matchingInherited[++index] = inheritedMethod;
502
			for (int j = i + 1; j < length; j++) {
503
			for (int j = i + 1; j < length; j++) {
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (-2 / +3 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 396-402 Link Here
396
		if (current == null && !isOrEnclosedByPrivateType) {
397
		if (current == null && !isOrEnclosedByPrivateType) {
397
			int length = inherited.length;
398
			int length = inherited.length;
398
			for (int i = 0; i < length; i++){
399
			for (int i = 0; i < length; i++){
399
				inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
400
				inherited[i].original().tagBits |= TagBits.IsAccessibleViaNonPrivateSub;
400
			}
401
			}
401
		}
402
		}
402
		if (current == null && this.type.isPublic()) {
403
		if (current == null && this.type.isPublic()) {
Lines 466-472 Link Here
466
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed,
467
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed,
467
			// inherited methods of super classes are too. current == null case handled already.
468
			// inherited methods of super classes are too. current == null case handled already.
468
			if (!isOrEnclosedByPrivateType && matchMethod == null && current != null) {
469
			if (!isOrEnclosedByPrivateType && matchMethod == null && current != null) {
469
				inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;	
470
				inherited[i].original().tagBits |= TagBits.IsAccessibleViaNonPrivateSub;	
470
			}
471
			}
471
			if (skip[i]) continue;
472
			if (skip[i]) continue;
472
			MethodBinding inheritedMethod = inherited[i];
473
			MethodBinding inheritedMethod = inherited[i];
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java (+10 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 1627-1630 Link Here
1627
public FieldBinding[] unResolvedFields() {
1628
public FieldBinding[] unResolvedFields() {
1628
	return this.fields;
1629
	return this.fields;
1629
}
1630
}
1631
1632
public void tagIndirectlyAccessibleFields() {
1633
	for (int i = 0; i < this.fields.length; i++) {
1634
		if (!this.fields[i].isPrivate())
1635
			this.fields[i].tagBits |= TagBits.IsAccessibleViaNonPrivateSub;
1636
	}
1637
	if (this.superclass.isPrivate())
1638
		((SourceTypeBinding)this.superclass).tagIndirectlyAccessibleFields();
1639
}
1630
}
1640
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java (+5 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 122-125 Link Here
122
123
123
	// set when type contains non-private constructor(s)
124
	// set when type contains non-private constructor(s)
124
	long HasNonPrivateConstructor = ASTNode.Bit53L;
125
	long HasNonPrivateConstructor = ASTNode.Bit53L;
126
127
	// set on a private class if it has a non-private subclass
128
	// set on a field/method of a private class if it is accessible via a non-private subclass
129
	long IsAccessibleViaNonPrivateSub = ASTNode.Bit54L;
125
}
130
}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java (+147 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
package org.eclipse.jdt.core.tests.compiler.regression;
12
13
Lines 5154-5159 Link Here
5154
		"----------\n");
5155
		"----------\n");
5155
}
5156
}
5156
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660
5157
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660
5158
// check independence of textual order
5159
public void test099a() {
5160
	this.runNegativeTest(
5161
		new String[] {
5162
			"X.java",
5163
			"public class X {\n" +
5164
			"   public class C extends B {\n" +
5165
		    "		public void foo(int a) {\n" +
5166
			"			System.out.println(\"Hello\");\n" +    
5167
			"		}\n" +
5168
		    "		public void foo(double a) {\n" +
5169
			"			System.out.println(\"Hello\");\n" +    
5170
			"		}\n" +
5171
			"		public void foo(boolean a) {\n" +
5172
			"			System.out.println(\"Hello\");\n" +    
5173
			"		}\n" +
5174
			"		public void foo(byte a) {\n" +
5175
			"			System.out.println(\"Hello\");\n" +     
5176
			"		}\n" +
5177
		    "   }\n" +
5178
			"   private class B extends A {\n" +
5179
			"		public void foo(int a) {\n" +
5180
			"   		System.out.println(\"Hello\");\n" +    
5181
			"   	}\n" +
5182
			"		public void foo(float a) {\n" +
5183
			"   		System.out.println(\"Hello\");\n" +    
5184
			"   	}\n" +
5185
			"   	public void foo(double a) {\n" +
5186
			"   		System.out.println(\"Hello\");\n" +    
5187
			"   	}\n" +
5188
			"   	public void foo(char a) {\n" +
5189
			"   		System.out.println(\"Hello\");\n" +    
5190
			"   	}\n" +
5191
			"   }\n" +
5192
			"   private class A {\n" +
5193
			"    	public void foo(int a) {\n" +
5194
			"   		System.out.println(\"Hello\");\n" +    
5195
			"    	}\n" +
5196
			"	    public void foo(float a) {\n" +
5197
			"   		System.out.println(\"Hello\");\n" + 
5198
			"   	}\n" +
5199
			"   	public void foo(boolean a) {\n" +
5200
			"   		System.out.println(\"Hello\");\n" +    
5201
			"   	}\n" +
5202
			"      	public void foo(Integer a) {\n" +
5203
			"   		System.out.println(\"Hello\");\n" +    
5204
			"   	}\n" +
5205
			"   }\n" + 
5206
			"}\n"
5207
		},
5208
		"----------\n" + 
5209
		"1. WARNING in X.java (at line 2)\n" + 
5210
		"	public class C extends B {\n" + 
5211
		"	             ^\n" + 
5212
		"Access to enclosing constructor X.B() is emulated by a synthetic accessor method\n" + 
5213
		"----------\n" + 
5214
		"2. WARNING in X.java (at line 16)\n" + 
5215
		"	private class B extends A {\n" + 
5216
		"	              ^\n" + 
5217
		"Access to enclosing constructor X.A() is emulated by a synthetic accessor method\n" + 
5218
		"----------\n" + 
5219
		"3. WARNING in X.java (at line 23)\n" + 
5220
		"	public void foo(double a) {\n" + 
5221
		"	            ^^^^^^^^^^^^^\n" + 
5222
		"The method foo(double) from the type X.B is never used locally\n" + 
5223
		"----------\n" + 
5224
		"4. WARNING in X.java (at line 31)\n" + 
5225
		"	public void foo(int a) {\n" + 
5226
		"	            ^^^^^^^^^^\n" + 
5227
		"The method foo(int) from the type X.A is never used locally\n" + 
5228
		"----------\n" + 
5229
		"5. WARNING in X.java (at line 34)\n" + 
5230
		"	public void foo(float a) {\n" + 
5231
		"	            ^^^^^^^^^^^^\n" + 
5232
		"The method foo(float) from the type X.A is never used locally\n" + 
5233
		"----------\n" + 
5234
		"6. WARNING in X.java (at line 37)\n" + 
5235
		"	public void foo(boolean a) {\n" + 
5236
		"	            ^^^^^^^^^^^^^^\n" + 
5237
		"The method foo(boolean) from the type X.A is never used locally\n" + 
5238
		"----------\n");
5239
}
5240
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660
5241
// check usage via super-call
5242
public void test099b() {
5243
	this.runNegativeTest(
5244
		new String[] {
5245
			"X.java",
5246
			"public class X {\n" +
5247
			"    private class A {\n" +
5248
			"    	public void foo(int a) {\n" +
5249
			"   		System.out.println(\"Hello\");\n" +    
5250
			"    	}\n" +
5251
			"	    public void foo(float a) {\n" +
5252
			"   		System.out.println(\"Hello\");\n" + 
5253
			"   	}\n" +
5254
			"   	public void foo(boolean a) {\n" +
5255
			"   		System.out.println(\"Hello\");\n" +    
5256
			"   	}\n" +
5257
			"      	public void foo(Integer a) {\n" +
5258
			"   		System.out.println(\"Hello\");\n" +    
5259
			"   	}\n" +
5260
			"   }\n" + 
5261
			"   private class B extends A {\n" +
5262
			"		public void foo(int a) {\n" +
5263
			"   		super.foo(a);\n" +    
5264
			"   	}\n" +
5265
			"		public void foo(float a) {\n" +
5266
			"   		super.foo(a);\n" +    
5267
			"   	}\n" +
5268
			"   	public void foo(double a) {\n" +
5269
			"   		System.out.println(\"Hello\");\n" +    
5270
			"   	}\n" +
5271
			"   	public void foo(char a) {\n" +
5272
			"   		System.out.println(\"Hello\");\n" +    
5273
			"   	}\n" +
5274
			"   }\n" +
5275
			"   public class C extends B {\n" +
5276
		    "		public void foo(int a) {\n" +
5277
			"			System.out.println(\"Hello\");\n" +    
5278
			"		}\n" +
5279
		    "		public void foo(double a) {\n" +
5280
			"			super.foo(a);\n" +    
5281
			"		}\n" +
5282
			"		public void foo(boolean a) {\n" +
5283
			"			super.foo(a);\n" +    
5284
			"		}\n" +
5285
			"		public void foo(byte a) {\n" +
5286
			"			System.out.println(\"Hello\");\n" +     
5287
			"		}\n" +
5288
		    "   }\n" +
5289
			"}\n"
5290
		},
5291
		"----------\n" + 
5292
		"1. WARNING in X.java (at line 16)\n" + 
5293
		"	private class B extends A {\n" + 
5294
		"	              ^\n" + 
5295
		"Access to enclosing constructor X.A() is emulated by a synthetic accessor method\n" + 
5296
		"----------\n" + 
5297
		"2. WARNING in X.java (at line 30)\n" + 
5298
		"	public class C extends B {\n" + 
5299
		"	             ^\n" + 
5300
		"Access to enclosing constructor X.B() is emulated by a synthetic accessor method\n" + 
5301
		"----------\n");
5302
}
5303
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660
5157
public void test100() {
5304
public void test100() {
5158
	this.runNegativeTest(
5305
	this.runNegativeTest(
5159
		new String[] {
5306
		new String[] {
(-)src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java (-1 / +28 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
11
 *     						bug 185682 - Increment/decrement operators mark local variables as read
12
 *     						bug 328281 - visibility leaks not detected when analyzing unused field in private class
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.core.tests.compiler.regression;
14
package org.eclipse.jdt.core.tests.compiler.regression;
13
15
Lines 2120-2124 Link Here
2120
			true/*shouldFlushOutputDirectory*/,
2122
			true/*shouldFlushOutputDirectory*/,
2121
			customOptions);
2123
			customOptions);
2122
}
2124
}
2125
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281
2126
public void test0052() {
2127
	Map customOptions = getCompilerOptions();
2128
	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
2129
	this.runConformTest(
2130
			new String[] {
2131
					"X.java",
2132
					"class X {\n" +
2133
					"    Y y = new Y();\n" +
2134
					"    private class Y {\n" +
2135
					"        int abc;\n" + 
2136
					"        Y() {\n" + 
2137
					"            abc++;\n" +    // not a relevant usage
2138
					"        }\n" +
2139
					"    }\n" +
2140
					"    class Z extends Y {}\n" + // makes 'abc' externally accessible
2141
					"}"
2142
			},
2143
			"",
2144
			null/*classLibraries*/,
2145
			true/*shouldFlushOutputDirectory*/,
2146
			null/*vmArguments*/,
2147
			customOptions,
2148
			null/*requestor*/);
2149
}
2123
2150
2124
}
2151
}

Return to bug 328281