Don't always mark array types as precise.

Array types are always final, as they cannot be sub-classed, they may be
assigned by types that aren't themselves, e.g. Object[] may be assigned a
String[]. Introduce CannotBeAssignedFromOtherTypes to capture this property
and use in the verifier instead of IsFinal to mark things as precise.

Change-Id: I34debd3164ca1b876be94b6722457cee6e1e9bd3
diff --git a/src/mirror/class.h b/src/mirror/class.h
index 0661b42..16ca2bd 100644
--- a/src/mirror/class.h
+++ b/src/mirror/class.h
@@ -235,6 +235,23 @@
     return (GetAccessFlags() & kAccClassIsPhantomReference) != 0;
   }
 
+  // Can references of this type be assigned to by things of another type? For non-array types
+  // this is a matter of whether sub-classes may exist - which they can't if the type is final.
+  // For array classes, where all the classes are final due to there being no sub-classes, an
+  // Object[] may be assigned to by a String[] but a String[] may not be assigned to by other
+  // types as the component is final.
+  bool CannotBeAssignedFromOtherTypes() const {
+    if (!IsArrayClass()) {
+      return IsFinal();
+    } else {
+      Class* component = GetComponentType();
+      if (component->IsPrimitive()) {
+        return false;
+      } else {
+        return component->CannotBeAssignedFromOtherTypes();
+      }
+    }
+  }
 
   String* GetName() const;  // Returns the cached name.
   void SetName(String* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);  // Sets the cached name.