Bug 515759: [9][compiler] Error is not reported when a class
instantiated via an anonymous diamond refers to inaccessible types

Change-Id: I354f1ede26f945f288fa6914fc7431599d6a13ee
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java
index d3cdb89..6e4e1c4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 IBM Corporation.
+ * Copyright (c) 2016, 2017 IBM Corporation.
  * 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
@@ -454,6 +454,83 @@
 		"The method toString(String) of type new Z<X>(){} must override or implement a supertype method\n" + 
 		"----------\n");
 }
+// Inaccessible type inferred for anonymous diamond is an error
+public void testBug488663_015() {
+	this.runNegativeTest(
+		new String[] {
+			"Test.java",
+			"public class Test<T> {\n" + 
+			"	private static class Inner {" +
+			"		public Inner(){}\n" +	
+			"	}\n" + 
+			"	<R> void print(I<R> i) {}\n" + 
+			"	public Inner get() {\n" + 
+			"		return new Inner();\n" + 
+			"	}\n" + 
+			"}\n",
+			"Z.java",
+			"class Z<T> implements I<T> {\n" + 
+			"	public Z(T t1) {}\n" + 
+			"	public String toString (T t) {\n" + 
+			"		return t.toString();\n" + 
+			"	}\n" + 
+			"}",
+			"X.java",
+			"public class X {\n" +  
+			"	public static void main(String[] args) {\n" + 
+			"		Test<String> t = new Test<>();\n" + 
+			"		t.print(new Z<>(t.get()) {\n" + 
+			"			\n" + 
+			"		});\n" + 
+			"	}\n" + 
+			"}\n" + 
+			"interface I<T> {\n" + 
+			"	String toString();\n" + 
+			"}"
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 4)\n" + 
+		"	t.print(new Z<>(t.get()) {\n" + 
+		"	            ^^^^^^^^^^^^\n" + 
+		"The type Test$Inner is not visible\n" + 
+		"----------\n");
+}
+// Inaccessible type inferred for anonymous diamond is an error - interface case
+public void testBug488663_016() {
+	this.runNegativeTest(
+		new String[] {
+			"Test.java",
+			"public class Test<T> {\n" + 
+			"	private static class Inner {" +
+			"		public Inner(){}\n" +	
+			"	}\n" + 
+			"	<R extends Inner> void print(I<R> i) {}\n" + 
+			"	public Inner get() {\n" + 
+			"		return new Inner();\n" + 
+			"	}\n" + 
+			"}\n",
+			"X.java",
+			"public class X {\n" +  
+			"	public static void main(String[] args) {\n" + 
+			"		Test<String> t = new Test<>();\n" + 
+			"		t.print(new I<>() {\n" + 
+			"			public String toString() {\n" + 
+			"				return \"\";\n" + 
+			"			}\n" + 
+			"		});\n" + 
+			"	}\n" + 
+			"}\n" + 
+			"interface I<T> {\n" + 
+			"	String toString();\n" + 
+			"}"
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 4)\n" + 
+		"	t.print(new I<>() {\n" + 
+		"	            ^^^^^\n" + 
+		"The type Test$Inner is not visible\n" + 
+		"----------\n");
+}
 public static Class testClass() {
 	return GenericsRegressionTest_9.class;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index b666225..06605ac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 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
@@ -523,9 +523,8 @@
 				if (constructorBinding == null)
 					return null;
 				this.resolvedType = this.anonymousType.binding;
-				// Check that inferred type is denotable
-				if (!checkTypeArgumentValidity((ParameterizedTypeBinding) receiverType, scope)) {
-					scope.problemReporter().anonymousDiamondWithNonDenotableTypeArguments(this.type, receiverType);
+				// Check that inferred type is valid
+				if (!validate((ParameterizedTypeBinding) receiverType, scope)) {
 					return this.resolvedType;
 				}
 			}
@@ -597,7 +596,7 @@
 		}
 	}
 
-	private boolean checkTypeArgumentValidity(final ParameterizedTypeBinding allocationType, final Scope scope) {
+	private boolean validate(final ParameterizedTypeBinding allocationType, final Scope scope) {
 		class ValidityInspector extends TypeBindingVisitor {
 			private boolean noErrors;
 
@@ -607,14 +606,23 @@
 
 			public boolean visit(IntersectionTypeBinding18 intersectionTypeBinding18) {
 				Arrays.sort(intersectionTypeBinding18.intersectingTypes, (t1, t2) -> t1.id - t2.id);
+				scope.problemReporter().anonymousDiamondWithNonDenotableTypeArguments(QualifiedAllocationExpression.this.type, allocationType);
 				return this.noErrors = false;  // stop traversal
 			}
 			public boolean visit(TypeVariableBinding typeVariable) {
 				if (typeVariable.isCapture()) {
+					scope.problemReporter().anonymousDiamondWithNonDenotableTypeArguments(QualifiedAllocationExpression.this.type, allocationType);
 					return this.noErrors = false;  // stop traversal
 				}
 				return true; // continue traversal
 			}
+			public boolean visit(ReferenceBinding ref) {
+				if (!ref.canBeSeenBy(scope)) {
+					scope.problemReporter().invalidType(QualifiedAllocationExpression.this.anonymousType, new ProblemReferenceBinding(ref.compoundName, ref, ProblemReasons.NotVisible));
+					return this.noErrors = false;
+				}
+				return true;
+			}
 			public boolean isValid() {
 				TypeBindingVisitor.visit(this, allocationType);
 				return this.noErrors;