Bug 475996 - NullPointerException in ASTNode.checkInvocationArgument
(ASTNode.java:340)

Change-Id: I8eb730049c6319bd56eee44f65c5e178b3c31eac
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PolymorphicSignatureTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PolymorphicSignatureTest.java
index 689147d..8a22160 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PolymorphicSignatureTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PolymorphicSignatureTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2014 IBM Corporation.
+ * Copyright (c) 2011, 2018 IBM Corporation.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -85,4 +85,20 @@
 				"}\n"
 			});
 	}
+	public void testBug475996() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"import java.lang.invoke.VarHandle;\n" +
+				"public class X<T> {\n" +
+				"	static class Token {}\n" +
+				"	Token NIL = new Token();\n" +
+				"	VarHandle RESULT;\n" +
+				"	void call(T t) {\n" +
+				"		RESULT.compareAndSet(this, null, (t==null) ? NIL : t);\n" +
+				"	}\n" +
+				"" +
+				"}\n"
+			});
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 2ec4fb7..142fbe2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -1217,7 +1217,7 @@
 	cachedInfo[index] = parameterizedGenericMethod;
 	return parameterizedGenericMethod;
 }
-public PolymorphicMethodBinding createPolymorphicMethod(MethodBinding originalPolymorphicMethod, TypeBinding[] parameters) {
+public PolymorphicMethodBinding createPolymorphicMethod(MethodBinding originalPolymorphicMethod, TypeBinding[] parameters, Scope scope) {
 	// cached info is array of already created polymorphic methods for this type
 	String key = new String(originalPolymorphicMethod.selector);
 	PolymorphicMethodBinding[] cachedInfo = (PolymorphicMethodBinding[]) this.uniquePolymorphicMethodBindings.get(key);
@@ -1230,7 +1230,12 @@
 		} else {
 			if (parameterTypeBinding.isPolyType()) {
 				PolyTypeBinding ptb = (PolyTypeBinding) parameterTypeBinding;
-				parametersTypeBinding[i] = ptb.expression.resolvedType;
+				if (scope instanceof BlockScope && ptb.expression.resolvedType == null) {
+					ptb.expression.setExpectedType(scope.getJavaLangObject());
+					parametersTypeBinding[i] = ptb.expression.resolveType((BlockScope) scope);
+				} else {
+					parametersTypeBinding[i] = ptb.expression.resolvedType;
+				}
 			} else {
 				parametersTypeBinding[i] = parameterTypeBinding.erasure();
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 0569b90..000a3c3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -867,7 +867,7 @@
 		if ((parameterCompatibilityLevel(method, arguments, tiebreakingVarargsMethods)) > NOT_COMPATIBLE) {
 			if ((method.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
 				// generate polymorphic method
-				return this.environment().createPolymorphicMethod(method, arguments);
+				return this.environment().createPolymorphicMethod(method, arguments, this);
 			}
 			return method;
 		}
@@ -1347,7 +1347,7 @@
 					exactMethod = computeCompatibleMethod(exactMethod, argumentTypes, invocationSite);
 				} else if ((exactMethod.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
 					// generate polymorphic method
-					return this.environment().createPolymorphicMethod(exactMethod, argumentTypes);
+					return this.environment().createPolymorphicMethod(exactMethod, argumentTypes, this);
 				}
 				return exactMethod;
 			}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
index aa84993..8d5a4c6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
@@ -431,7 +431,7 @@
 					for (int j = 0; j < length; j++) {
 						parameterTypes[j] = getType(typeParameters[j]);
 					}
-					PolymorphicMethodBinding polymorphicMethod = this.environment.createPolymorphicMethod(method, parameterTypes);
+					PolymorphicMethodBinding polymorphicMethod = this.environment.createPolymorphicMethod(method, parameterTypes, this.scope);
 					this.methodBinding = polymorphicMethod;
 					this.methodBinding = this.environment.updatePolymorphicMethodReturnType(
 							polymorphicMethod,