langtools/src/share/classes/com/sun/tools/javac/code/Types.java
changeset 7643 a067a0cda531
parent 7637 467bc8fc514e
child 7681 1f0819a3341f
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 13 14:08:01 2010 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 13 15:11:00 2010 -0800
@@ -33,6 +33,7 @@
 
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
+import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.comp.Check;
 
 import static com.sun.tools.javac.code.Type.*;
@@ -272,13 +273,36 @@
     public boolean isConvertible(Type t, Type s, Warner warn) {
         boolean tPrimitive = t.isPrimitive();
         boolean sPrimitive = s.isPrimitive();
-        if (tPrimitive == sPrimitive)
+        if (tPrimitive == sPrimitive) {
+            checkUnsafeVarargsConversion(t, s, warn);
             return isSubtypeUnchecked(t, s, warn);
+        }
         if (!allowBoxing) return false;
         return tPrimitive
             ? isSubtype(boxedClass(t).type, s)
             : isSubtype(unboxedType(t), s);
     }
+    //where
+    private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
+        if (t.tag != ARRAY || isReifiable(t)) return;
+        ArrayType from = (ArrayType)t;
+        boolean shouldWarn = false;
+        switch (s.tag) {
+            case ARRAY:
+                ArrayType to = (ArrayType)s;
+                shouldWarn = from.isVarargs() &&
+                        !to.isVarargs() &&
+                        !isReifiable(from);
+                break;
+            case CLASS:
+                shouldWarn = from.isVarargs() &&
+                        isSubtype(from, s);
+                break;
+        }
+        if (shouldWarn) {
+            warn.warn(LintCategory.VARARGS);
+        }
+    }
 
     /**
      * Is t a subtype of or convertiable via boxing/unboxing
@@ -301,9 +325,18 @@
      */
     public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
         if (t.tag == ARRAY && s.tag == ARRAY) {
-            return (((ArrayType)t).elemtype.tag <= lastBaseTag)
-                ? isSameType(elemtype(t), elemtype(s))
-                : isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
+            if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
+                return isSameType(elemtype(t), elemtype(s));
+            } else {
+                ArrayType from = (ArrayType)t;
+                ArrayType to = (ArrayType)s;
+                if (from.isVarargs() &&
+                        !to.isVarargs() &&
+                        !isReifiable(from)) {
+                    warn.warn(LintCategory.VARARGS);
+                }
+                return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
+            }
         } else if (isSubtype(t, s)) {
             return true;
         }
@@ -319,9 +352,9 @@
             Type t2 = asSuper(t, s.tsym);
             if (t2 != null && t2.isRaw()) {
                 if (isReifiable(s))
-                    warn.silentUnchecked();
+                    warn.silentWarn(LintCategory.UNCHECKED);
                 else
-                    warn.warnUnchecked();
+                    warn.warn(LintCategory.UNCHECKED);
                 return true;
             }
         }
@@ -922,6 +955,7 @@
         if (warn != warnStack.head) {
             try {
                 warnStack = warnStack.prepend(warn);
+                checkUnsafeVarargsConversion(t, s, warn);
                 return isCastable.visit(t,s);
             } finally {
                 warnStack = warnStack.tail;
@@ -964,7 +998,7 @@
 
                 if (s.tag == TYPEVAR) {
                     if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
-                        warnStack.head.warnUnchecked();
+                        warnStack.head.warn(LintCategory.UNCHECKED);
                         return true;
                     } else {
                         return false;
@@ -980,8 +1014,8 @@
                         if (!visit(intf, s))
                             return false;
                     }
-                    if (warnStack.head.unchecked == true)
-                        oldWarner.warnUnchecked();
+                    if (warnStack.head.hasLint(LintCategory.UNCHECKED))
+                        oldWarner.warn(LintCategory.UNCHECKED);
                     return true;
                 }
 
@@ -996,13 +1030,13 @@
                         || isSubtype(erasure(s), erasure(t))) {
                         if (!upcast && s.tag == ARRAY) {
                             if (!isReifiable(s))
-                                warnStack.head.warnUnchecked();
+                                warnStack.head.warn(LintCategory.UNCHECKED);
                             return true;
                         } else if (s.isRaw()) {
                             return true;
                         } else if (t.isRaw()) {
                             if (!isUnbounded(s))
-                                warnStack.head.warnUnchecked();
+                                warnStack.head.warn(LintCategory.UNCHECKED);
                             return true;
                         }
                         // Assume |a| <: |b|
@@ -1035,7 +1069,7 @@
                                 && !disjointTypes(aLow.allparams(), lowSub.allparams())) {
                                 if (upcast ? giveWarning(a, b) :
                                     giveWarning(b, a))
-                                    warnStack.head.warnUnchecked();
+                                    warnStack.head.warn(LintCategory.UNCHECKED);
                                 return true;
                             }
                         }
@@ -1072,7 +1106,7 @@
                     return true;
                 case TYPEVAR:
                     if (isCastable(s, t, Warner.noWarnings)) {
-                        warnStack.head.warnUnchecked();
+                        warnStack.head.warn(LintCategory.UNCHECKED);
                         return true;
                     } else {
                         return false;
@@ -1101,7 +1135,7 @@
                     if (isSubtype(t, s)) {
                         return true;
                     } else if (isCastable(t.bound, s, Warner.noWarnings)) {
-                        warnStack.head.warnUnchecked();
+                        warnStack.head.warn(LintCategory.UNCHECKED);
                         return true;
                     } else {
                         return false;
@@ -2906,7 +2940,7 @@
             return true;
         if (!isSubtype(r1.getReturnType(), erasure(r2res)))
             return false;
-        warner.warnUnchecked();
+        warner.warn(LintCategory.UNCHECKED);
         return true;
     }
 
@@ -3122,7 +3156,7 @@
             commonSupers = commonSupers.tail;
         }
         if (giveWarning && !isReifiable(reverse ? from : to))
-            warn.warnUnchecked();
+            warn.warn(LintCategory.UNCHECKED);
         if (!source.allowCovariantReturns())
             // reject if there is a common method signature with
             // incompatible return types.
@@ -3156,7 +3190,7 @@
             chk.checkCompatibleAbstracts(warn.pos(), from, to);
         if (!isReifiable(target) &&
             (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
-            warn.warnUnchecked();
+            warn.warn(LintCategory.UNCHECKED);
         return true;
     }