GROOVY-9270: add checks for invalid instanceof reference types

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.20.2
diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
index 14847e7..7d476b7 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
@@ -802,6 +802,14 @@
             visitor = new LabelVerifier(source);
             visitor.visitClass(classNode);
 
+            visitor = new InstanceOfVerifier() {
+                @Override
+                protected SourceUnit getSourceUnit() {
+                    return source;
+                }
+            };
+            visitor.visitClass(classNode);
+
             visitor = new ClassCompletionVerifier(source);
             visitor.visitClass(classNode);
 
diff --git a/src/main/java/org/codehaus/groovy/control/InstanceOfVerifier.java b/src/main/java/org/codehaus/groovy/control/InstanceOfVerifier.java
new file mode 100644
index 0000000..8eacaf2
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/control/InstanceOfVerifier.java
@@ -0,0 +1,58 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.control;
+
+import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.expr.BinaryExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.syntax.Types;
+
+public abstract class InstanceOfVerifier extends ClassCodeVisitorSupport {
+
+    @Override
+    public void visitBinaryExpression(BinaryExpression expression) {
+        if (expression.getOperation().isA(Types.INSTANCEOF_OPERATOR) &&
+                expression.getRightExpression() instanceof ClassExpression) {
+            ClassNode referenceType = expression.getRightExpression().getType();
+
+            if (ClassHelper.isPrimitiveType(referenceType)) {
+                addTypeError(expression.getRightExpression(), "primitive type " + referenceType.getName());
+            } else {
+                while (referenceType.isArray()) {
+                    referenceType = referenceType.getComponentType();
+                }
+
+                if (referenceType.isGenericsPlaceHolder()) {
+                    addTypeError(expression.getRightExpression(), "type parameter " + referenceType.getUnresolvedName() +
+                        ". Use its erasure " + referenceType.getNameWithoutPackage() + " instead since further generic type information will be erased at runtime");
+                } else if (referenceType.getGenericsTypes() != null) {
+                    // TODO: Cannot perform instanceof check against parameterized type Class<Type>. Use the form Class<?> instead since further eneric type information will be erased at runtime
+                }
+            }
+        }
+        super.visitBinaryExpression(expression);
+    }
+
+    private void addTypeError(Expression referenceExpr, String referenceType) {
+        addError("Cannot perform instanceof check against " + referenceType, referenceExpr);
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/syntax/Types.java b/src/main/java/org/codehaus/groovy/syntax/Types.java
index 26e12b9..0464dc6 100644
--- a/src/main/java/org/codehaus/groovy/syntax/Types.java
+++ b/src/main/java/org/codehaus/groovy/syntax/Types.java
@@ -304,6 +304,7 @@
     public static final int REGEX_COMPARISON_OPERATOR = 1105;  // =~, etc.
     public static final int DEREFERENCE_OPERATOR = 1106;  // ., ->
     public static final int BITWISE_OPERATOR = 1107;  // |, &, <<, >>, >>>, ^, ~
+    public static final int INSTANCEOF_OPERATOR = 1108; // instanceof, !instanceof
 
     public static final int PREFIX_OPERATOR = 1200;  // ++, !, etc.
     public static final int POSTFIX_OPERATOR = 1210;  // ++, etc.
@@ -414,6 +415,9 @@
             case COMPARISON_OPERATOR:
                 return specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO;
 
+            case INSTANCEOF_OPERATOR:
+                return specific == KEYWORD_INSTANCEOF || specific == COMPARE_NOT_INSTANCEOF;
+
             case MATH_OPERATOR:
                 return (specific >= PLUS && specific <= RIGHT_SHIFT_UNSIGNED) || (specific >= NOT && specific <= LOGICAL_AND)
                         || (specific >= BITWISE_OR && specific <= BITWISE_XOR);
diff --git a/src/test/groovy/bugs/Groovy9270.groovy b/src/test/groovy/bugs/Groovy9270.groovy
new file mode 100644
index 0000000..c4c794a
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9270.groovy
@@ -0,0 +1,96 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+import static groovy.test.GroovyAssert.shouldFail
+
+@CompileStatic
+final class Groovy9270 {
+
+    @Test
+    void testInstanceOfPrimitive1() {
+        def err = shouldFail '''
+            void meth(obj) {
+                if (obj instanceof int) {
+                    // ...
+                }
+            }
+        '''
+
+        assert err =~ / Cannot perform instanceof check against primitive type int/
+    }
+
+    @Test
+    void testInstanceOfPrimitive2() {
+        def err = shouldFail '''
+            void meth(obj) {
+                if (obj !instanceof int) {
+                    // ...
+                }
+            }
+        '''
+
+        assert err =~ / Cannot perform instanceof check against primitive type int/
+    }
+
+    @Test
+    void testInstanceOfPrimitiveArray() {
+        assertScript '''
+            void meth(obj) {
+                if (obj instanceof double[]) {
+                    // ...
+                }
+            }
+        '''
+    }
+
+    @Test
+    void testInstanceOfTypeParameter1() {
+        def err = shouldFail '''
+            class C<T extends Number> {
+                void meth(obj) {
+                    if (obj instanceof T) {
+                        // ...
+                    }
+                }
+            }
+        '''
+
+        assert err =~ / Cannot perform instanceof check against type parameter T/
+    }
+
+    @Test
+    void testInstanceOfTypeParameter2() {
+        def err = shouldFail '''
+            class C<T> {
+                void meth(obj) {
+                    if (obj instanceof T[]) {
+                        // ...
+                    }
+                }
+            }
+        '''
+
+        assert err =~ / Cannot perform instanceof check against type parameter T/
+    }
+}