Bug 545387 - [11] [compiler] code not running after nesting impl

Change-Id: I14f0b3eced1dd3d0614f5ab0075c4361caecf4ec
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP181NestTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP181NestTest.java
index d8bc54b..165fc6a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP181NestTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP181NestTest.java
@@ -1386,6 +1386,53 @@
 	verifyOutputNegative(XYZFile, "invokestatic X.access$0(X, int)");
 }
 
+public void testBug545387_01() throws Exception {
+	Map<String, String> options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
+	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
+
+	this.runConformTest(
+			new String[] {
+					"pack1/X.java",
+					"package pack1;\n"+
+					"public class X {\n"+
+					"	public class Inner1 {\n"+
+					"		private void foo() {\n"+
+					"			System.out.println(\"hello\");;\n"+
+					"		}\n"+
+					"	}\n"+
+					"	public class Sub1 extends Inner1 {\n"+
+					"		public class Sub2 {\n"+
+					"			void testFoo() {\n"+
+					"				Sub1.super.foo();\n"+
+					"			}\n"+
+					"		}\n"+
+					"		void testFoo() {\n"+
+					"			(new Sub2()).testFoo();\n"+
+					"		}\n"+
+					"	}\n"+
+					"	public static void main(String[] args) {\n"+
+					"		Sub1 s1 = getS1();\n"+
+					"		s1.testFoo();\n"+
+					"	}\n"+
+					"	public static Sub1 getS1() {\n"+
+					"		return new X().new Sub1();\n"+
+					"	}\n"+
+					"}\n",
+			},
+			"hello",
+			options
+	);
+
+	String XSub1 = getClassFileContents("pack1/X$Sub1.class", ClassFileBytesDisassembler.SYSTEM);
+	String XSub1Sub2 = getClassFileContents("pack1/X$Sub1$Sub2.class", ClassFileBytesDisassembler.SYSTEM);
+	verifyOutputPositive(XSub1Sub2, "Nest Host: #29 pack1/X");
+
+	// the access is via synthetic emulation.
+//	verifyOutputNegative(XSub1, "access$");
+//	verifyOutputNegative(XSub1Sub2, "invokestatic X.access");
+}
+
 public static Class testClass() {
 	return JEP181NestTest.class;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 2e52f5a..6e7970e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -549,9 +549,10 @@
 	// if method from parameterized type got found, use the original method at codegen time
 	MethodBinding codegenBinding = this.binding.original();
 	if (this.binding.isPrivate()){
-
+		boolean useNesting = currentScope.enclosingSourceType().isNestmateOf(codegenBinding.declaringClass) &&
+				!(this.receiver instanceof QualifiedSuperReference);
 		// depth is set for both implicit and explicit access (see MethodBinding#canBeSeenBy)
-		if (!currentScope.enclosingSourceType().isNestmateOf(codegenBinding.declaringClass) &&
+		if (!useNesting &&
 				TypeBinding.notEquals(currentScope.enclosingSourceType(), codegenBinding.declaringClass)){
 			this.syntheticAccessor = ((SourceTypeBinding)codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, false /* not super access there */);
 			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);