changeset 1275:517f0789bd4e

Merge
author lana
date Mon, 09 Apr 2012 21:58:05 -0700
parents e4241f09e2b6 01e7924ea479
children 6b105afbb77c c35b158e2290
files
diffstat 61 files changed, 1988 insertions(+), 1555 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Apr 09 21:58:05 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -221,7 +221,7 @@
 
     /** Flag that marks a hypothetical method that need not really be
      *  generated in the binary, but is present in the symbol table to
-     *  simplify checking for erasure clashes.
+     *  simplify checking for erasure clashes - also used for 292 poly sig methods.
      */
     public static final long HYPOTHETICAL   = 1L<<37;
 
@@ -236,26 +236,20 @@
     public static final long UNION = 1L<<39;
 
     /**
-     * Flag that marks a signature-polymorphic invoke method.
-     * (These occur inside java.lang.invoke.MethodHandle.)
-     */
-    public static final long POLYMORPHIC_SIGNATURE = 1L<<40;
-
-    /**
      * Flag that marks a special kind of bridge methods (the ones that
      * come from restricted supertype bounds)
      */
-    public static final long OVERRIDE_BRIDGE = 1L<<41;
+    public static final long OVERRIDE_BRIDGE = 1L<<40;
 
     /**
      * Flag that marks an 'effectively final' local variable
      */
-    public static final long EFFECTIVELY_FINAL = 1L<<42;
+    public static final long EFFECTIVELY_FINAL = 1L<<41;
 
     /**
      * Flag that marks non-override equivalent methods with the same signature
      */
-    public static final long CLASH = 1L<<43;
+    public static final long CLASH = 1L<<42;
 
     /** Modifier masks.
      */
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Apr 09 21:58:05 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -202,16 +202,6 @@
         return (flags() & INTERFACE) != 0;
     }
 
-    /** Recognize if this symbol was marked @PolymorphicSignature in the source. */
-    public boolean isPolymorphicSignatureGeneric() {
-        return (flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == POLYMORPHIC_SIGNATURE;
-    }
-
-    /** Recognize if this symbol was split from a @PolymorphicSignature symbol in the source. */
-    public boolean isPolymorphicSignatureInstance() {
-        return (flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == (POLYMORPHIC_SIGNATURE | HYPOTHETICAL);
-    }
-
     /** Is this symbol declared (directly or indirectly) local
      *  to a method or variable initializer?
      *  Also includes fields of inner classes which are in
@@ -1316,6 +1306,25 @@
                     getKind() == ElementKind.INSTANCE_INIT;
         }
 
+        /**
+         * A polymorphic signature method (JLS SE 7, 8.4.1) is a method that
+         * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes
+         * a single variable arity parameter (iii) whose declared type is Object[],
+         * (iv) has a return type of Object and (v) is native.
+         */
+        public boolean isSignaturePolymorphic(Types types) {
+            List<Type> argtypes = type.getParameterTypes();
+            Type firstElemType = argtypes.nonEmpty() ?
+                    types.elemtype(argtypes.head) :
+                    null;
+            return owner == types.syms.methodHandleType.tsym &&
+                    argtypes.length() == 1 &&
+                    firstElemType != null &&
+                    types.isSameType(firstElemType, types.syms.objectType) &&
+                    types.isSameType(type.getReturnType(), types.syms.objectType) &&
+                    (flags() & NATIVE) != 0;
+        }
+
         public Attribute getDefaultValue() {
             return defaultValue;
         }
--- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Apr 09 21:58:05 2012 -0700
@@ -127,7 +127,6 @@
     public final Type serializableType;
     public final Type methodHandleType;
     public final Type nativeHeaderType;
-    public final Type polymorphicSignatureType;
     public final Type throwableType;
     public final Type errorType;
     public final Type interruptedExceptionType;
@@ -436,7 +435,6 @@
         throwableType = enterClass("java.lang.Throwable");
         serializableType = enterClass("java.io.Serializable");
         methodHandleType = enterClass("java.lang.invoke.MethodHandle");
-        polymorphicSignatureType = enterClass("java.lang.invoke.MethodHandle$PolymorphicSignature");
         errorType = enterClass("java.lang.Error");
         illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
         interruptedExceptionType = enterClass("java.lang.InterruptedException");
@@ -483,7 +481,6 @@
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
         synthesizeEmptyInterfaceIfMissing(serializableType);
-        synthesizeEmptyInterfaceIfMissing(polymorphicSignatureType);
         synthesizeBoxTypeIfMissing(doubleType);
         synthesizeBoxTypeIfMissing(floatType);
         synthesizeBoxTypeIfMissing(voidType);
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Apr 09 21:58:05 2012 -0700
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.comp.Check.CheckContext;
 
 import com.sun.source.tree.IdentifierTree;
 import com.sun.source.tree.MemberSelectTree;
@@ -132,6 +133,11 @@
         findDiamonds = options.get("findDiamond") != null &&
                  source.allowDiamond();
         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
+
+        statInfo = new ResultInfo(NIL, Type.noType);
+        varInfo = new ResultInfo(VAR, Type.noType);
+        unknownExprInfo = new ResultInfo(VAL, Type.noType);
+        unknownTypeInfo = new ResultInfo(TYP, Type.noType);
     }
 
     /** Switch: relax some constraints for retrofit mode.
@@ -204,7 +210,7 @@
     Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) {
         if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
             if ((ownkind & ~resultInfo.pkind) == 0) {
-                owntype = chk.checkType(tree.pos(), owntype, resultInfo.pt, errKey);
+                owntype = resultInfo.check(tree, owntype);
             } else {
                 log.error(tree.pos(), "unexpected.type",
                           kindNames(resultInfo.pkind),
@@ -394,20 +400,30 @@
         }
     }
 
-    static class ResultInfo {
+    class ResultInfo {
         int pkind;
         Type pt;
+        CheckContext checkContext;
 
         ResultInfo(int pkind, Type pt) {
+            this(pkind, pt, chk.basicHandler);
+        }
+
+        protected ResultInfo(int pkind, Type pt, CheckContext checkContext) {
             this.pkind = pkind;
             this.pt = pt;
+            this.checkContext = checkContext;
+        }
+
+        protected Type check(DiagnosticPosition pos, Type found) {
+            return chk.checkType(pos, found, pt, checkContext);
         }
     }
 
-    private final ResultInfo statInfo = new ResultInfo(NIL, Type.noType);
-    private final ResultInfo varInfo = new ResultInfo(VAR, Type.noType);
-    private final ResultInfo unknownExprInfo = new ResultInfo(VAL, Type.noType);
-    private final ResultInfo unknownTypeInfo = new ResultInfo(TYP, Type.noType);
+    private final ResultInfo statInfo;
+    private final ResultInfo varInfo;
+    private final ResultInfo unknownExprInfo;
+    private final ResultInfo unknownTypeInfo;
 
     Type pt() {
         return resultInfo.pt;
@@ -429,10 +445,6 @@
      */
     ResultInfo resultInfo;
 
-    /** Visitor argument: the error key to be generated when a type error occurs
-     */
-    String errKey;
-
     /** Visitor result: the computed type.
      */
     Type result;
@@ -445,17 +457,11 @@
      *  @param resultInfo   The result info visitor argument.
      */
     private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
-        return attribTree(tree, env, resultInfo, "incompatible.types");
-    }
-
-    private Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, String errKey) {
         Env<AttrContext> prevEnv = this.env;
         ResultInfo prevResult = this.resultInfo;
-        String prevErrKey = this.errKey;
         try {
             this.env = env;
             this.resultInfo = resultInfo;
-            this.errKey = errKey;
             tree.accept(this);
             if (tree == breakTree)
                 throw new BreakAttr(env);
@@ -466,18 +472,13 @@
         } finally {
             this.env = prevEnv;
             this.resultInfo = prevResult;
-            this.errKey = prevErrKey;
         }
     }
 
     /** Derived visitor method: attribute an expression tree.
      */
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
-        return attribExpr(tree, env, pt, "incompatible.types");
-    }
-
-    public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt, String key) {
-        return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType), key);
+        return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType));
     }
 
     /** Derived visitor method: attribute an expression tree with
@@ -1121,9 +1122,16 @@
             localEnv;
         // Attribute resource declarations
         for (JCTree resource : tree.resources) {
+            CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
+                @Override
+                public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
+                    chk.basicHandler.report(pos, found, req, diags.fragment("try.not.applicable.to.type", found));
+                }
+            };
+            ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
             if (resource.hasTag(VARDEF)) {
                 attribStat(resource, tryEnv);
-                chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type");
+                twrResult.check(resource, resource.type);
 
                 //check that resource type cannot throw InterruptedException
                 checkAutoCloseable(resource.pos(), localEnv, resource.type);
@@ -1131,7 +1139,7 @@
                 VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
                 var.setData(ElementKind.RESOURCE_VARIABLE);
             } else {
-                attribExpr(resource, tryEnv, syms.autoCloseableType, "try.not.applicable.to.type");
+                attribTree(resource, tryEnv, twrResult);
             }
         }
         // Attribute body
@@ -1846,7 +1854,7 @@
     }
 
     Type attribDiamond(Env<AttrContext> env,
-                        JCNewClass tree,
+                        final JCNewClass tree,
                         Type clazztype,
                         List<Type> argtypes,
                         List<Type> typeargtypes) {
@@ -1886,25 +1894,17 @@
             clazztype = syms.errType;
         }
 
-        if (clazztype.tag == FORALL && !pt().isErroneous()) {
-            //if the resolved constructor's return type has some uninferred
-            //type-variables, infer them using the expected type and declared
-            //bounds (JLS 15.12.2.8).
+        if (clazztype.tag == FORALL && !resultInfo.pt.isErroneous()) {
             try {
-                clazztype = infer.instantiateExpr((ForAll) clazztype,
-                        pt().tag == NONE ? syms.objectType : pt(),
-                        Warner.noWarnings);
+                clazztype = resultInfo.checkContext.rawInstantiatePoly((ForAll)clazztype, pt(), Warner.noWarnings);
             } catch (Infer.InferenceException ex) {
                 //an error occurred while inferring uninstantiated type-variables
-                log.error(tree.clazz.pos(),
-                        "cant.apply.diamond.1",
-                        diags.fragment("diamond", clazztype.tsym),
-                        ex.diagnostic);
+                resultInfo.checkContext.report(tree.clazz.pos(), clazztype, resultInfo.pt,
+                        diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", clazztype.tsym), ex.diagnostic));
             }
         }
-        return chk.checkClassType(tree.clazz.pos(),
-                clazztype,
-                true);
+
+        return chk.checkClassType(tree.clazz.pos(), clazztype, true);
     }
 
     /** Make an attributed null check tree.
@@ -2106,6 +2106,7 @@
         if (exprtype.constValue() != null)
             owntype = cfolder.coerce(exprtype, owntype);
         result = check(tree, capture(owntype), VAL, resultInfo);
+        chk.checkRedundantCast(localEnv, tree);
     }
 
     public void visitTypeTest(JCInstanceOf tree) {
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Apr 09 21:58:05 2012 -0700
@@ -269,23 +269,6 @@
         else return syms.errType;
     }
 
-    /** Report a type error.
-     *  @param pos        Position to be used for error reporting.
-     *  @param problem    A string describing the error.
-     *  @param found      The type that was found.
-     *  @param req        The type that was required.
-     */
-    Type typeError(DiagnosticPosition pos, Object problem, Type found, Type req) {
-        log.error(pos, "prob.found.req",
-                  problem, found, req);
-        return types.createErrorType(found);
-    }
-
-    Type typeError(DiagnosticPosition pos, String problem, Type found, Type req, Object explanation) {
-        log.error(pos, "prob.found.req.1", problem, found, req, explanation);
-        return types.createErrorType(found);
-    }
-
     /** Report an error that wrong type tag was found.
      *  @param pos        Position to be used for error reporting.
      *  @param required   An internationalized string describing the type tag
@@ -430,6 +413,86 @@
  * Type Checking
  **************************************************************************/
 
+    /**
+     * A check context is an object that can be used to perform compatibility
+     * checks - depending on the check context, meaning of 'compatibility' might
+     * vary significantly.
+     */
+    interface CheckContext {
+        /**
+         * Is type 'found' compatible with type 'req' in given context
+         */
+        boolean compatible(Type found, Type req, Warner warn);
+        /**
+         * Instantiate a ForAll type against a given target type 'req' in given context
+         */
+        Type rawInstantiatePoly(ForAll found, Type req, Warner warn);
+        /**
+         * Report a check error
+         */
+        void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details);
+        /**
+         * Obtain a warner for this check context
+         */
+        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
+    }
+
+    /**
+     * This class represent a check context that is nested within another check
+     * context - useful to check sub-expressions. The default behavior simply
+     * redirects all method calls to the enclosing check context leveraging
+     * the forwarding pattern.
+     */
+    static class NestedCheckContext implements CheckContext {
+        CheckContext enclosingContext;
+
+        NestedCheckContext(CheckContext enclosingContext) {
+            this.enclosingContext = enclosingContext;
+        }
+
+        public boolean compatible(Type found, Type req, Warner warn) {
+            return enclosingContext.compatible(found, req, warn);
+        }
+
+        public Type rawInstantiatePoly(ForAll found, Type req, Warner warn) {
+            return enclosingContext.rawInstantiatePoly(found, req, warn);
+        }
+
+        public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
+            enclosingContext.report(pos, found, req, details);
+        }
+
+        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
+            return enclosingContext.checkWarner(pos, found, req);
+        }
+    }
+
+    /**
+     * Check context to be used when evaluating assignment/return statements
+     */
+    CheckContext basicHandler = new CheckContext() {
+        public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
+            if (details == null) {
+                log.error(pos, "prob.found.req", found, req);
+            } else {
+                log.error(pos, "prob.found.req.1", details);
+            }
+        }
+        public boolean compatible(Type found, Type req, Warner warn) {
+            return types.isAssignable(found, req, warn);
+        }
+
+        public Type rawInstantiatePoly(ForAll found, Type req, Warner warn) {
+            if (req.tag == NONE)
+                req = found.qtype.tag <= VOID ? found.qtype : syms.objectType;
+            return infer.instantiateExpr(found, req, warn);
+        }
+
+        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
+            return convertWarner(pos, found, req);
+        }
+    };
+
     /** Check that a given type is assignable to a given proto-type.
      *  If it is, return the type, otherwise return errType.
      *  @param pos        Position to be used for error reporting.
@@ -437,64 +500,54 @@
      *  @param req        The type that was required.
      */
     Type checkType(DiagnosticPosition pos, Type found, Type req) {
-        return checkType(pos, found, req, "incompatible.types");
+        return checkType(pos, found, req, basicHandler);
     }
 
-    Type checkType(DiagnosticPosition pos, Type found, Type req, String errKey) {
+    Type checkType(final DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
         if (req.tag == ERROR)
             return req;
-        if (found.tag == FORALL)
-            return instantiatePoly(pos, (ForAll)found, req, convertWarner(pos, found, req));
+        if (found.tag == FORALL) {
+            ForAll fa = (ForAll)found;
+            Type owntype = instantiatePoly(pos, checkContext, fa, req, checkContext.checkWarner(pos, found, req));
+            return checkType(pos, owntype, req, checkContext);
+        }
         if (req.tag == NONE)
             return found;
-        if (types.isAssignable(found, req, convertWarner(pos, found, req)))
+        if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
             return found;
-        if (found.tag <= DOUBLE && req.tag <= DOUBLE)
-            return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req);
-        if (found.isSuperBound()) {
-            log.error(pos, "assignment.from.super-bound", found);
+        } else {
+            if (found.tag <= DOUBLE && req.tag <= DOUBLE) {
+                checkContext.report(pos, found, req, diags.fragment("possible.loss.of.precision"));
+                return types.createErrorType(found);
+            }
+            checkContext.report(pos, found, req, null);
             return types.createErrorType(found);
         }
-        if (req.isExtendsBound()) {
-            log.error(pos, "assignment.to.extends-bound", req);
-            return types.createErrorType(found);
-        }
-        return typeError(pos, diags.fragment(errKey), found, req);
     }
 
     /** Instantiate polymorphic type to some prototype, unless
      *  prototype is `anyPoly' in which case polymorphic type
      *  is returned unchanged.
      */
-    Type instantiatePoly(DiagnosticPosition pos, ForAll t, Type pt, Warner warn) throws Infer.NoInstanceException {
-        if (pt == Infer.anyPoly && complexInference) {
-            return t;
-        } else if (pt == Infer.anyPoly || pt.tag == NONE) {
-            Type newpt = t.qtype.tag <= VOID ? t.qtype : syms.objectType;
-            return instantiatePoly(pos, t, newpt, warn);
-        } else if (pt.tag == ERROR) {
-            return pt;
-        } else {
-            try {
-                return infer.instantiateExpr(t, pt, warn);
-            } catch (Infer.NoInstanceException ex) {
+    Type instantiatePoly(DiagnosticPosition pos, CheckContext checkContext, ForAll t, Type pt, Warner warn) throws Infer.NoInstanceException {
+        try {
+            return checkContext.rawInstantiatePoly(t, pt, warn);
+        } catch (final Infer.NoInstanceException ex) {
+            JCDiagnostic d = ex.getDiagnostic();
+            if (d != null) {
                 if (ex.isAmbiguous) {
-                    JCDiagnostic d = ex.getDiagnostic();
-                    log.error(pos,
-                              "undetermined.type" + (d!=null ? ".1" : ""),
-                              t, d);
-                    return types.createErrorType(pt);
-                } else {
-                    JCDiagnostic d = ex.getDiagnostic();
-                    return typeError(pos,
-                                     diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
-                                     t, pt);
+                    d = diags.fragment("undetermined.type", t, d);
                 }
-            } catch (Infer.InvalidInstanceException ex) {
-                JCDiagnostic d = ex.getDiagnostic();
-                log.error(pos, "invalid.inferred.types", t.tvars, d);
-                return types.createErrorType(pt);
             }
+            checkContext.report(pos, t, pt, d);
+            return types.createErrorType(pt);
+        } catch (Infer.InvalidInstanceException ex) {
+            JCDiagnostic d = ex.getDiagnostic();
+            if (d != null) {
+                d = diags.fragment("invalid.inferred.types", t.tvars, d);
+            }
+            checkContext.report(pos, t, pt, d);
+            return types.createErrorType(pt);
         }
     }
 
@@ -505,17 +558,48 @@
      *  @param req        The target type of the cast.
      */
     Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
+        return checkCastable(pos, found, req, basicHandler);
+    }
+    Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
         if (found.tag == FORALL) {
-            instantiatePoly(pos, (ForAll) found, req, castWarner(pos, found, req));
+            instantiatePoly(pos, basicHandler, (ForAll) found, req, castWarner(pos, found, req));
             return req;
         } else if (types.isCastable(found, req, castWarner(pos, found, req))) {
             return req;
         } else {
-            return typeError(pos,
-                             diags.fragment("inconvertible.types"),
-                             found, req);
+            checkContext.report(pos, found, req, diags.fragment("inconvertible.types", found, req));
+            return types.createErrorType(found);
         }
     }
+
+    /** Check for redundant casts (i.e. where source type is a subtype of target type)
+     * The problem should only be reported for non-292 cast
+     */
+    public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) {
+        if (!tree.type.isErroneous() &&
+            (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
+            && types.isSameType(tree.expr.type, tree.clazz.type)
+            && !is292targetTypeCast(tree)) {
+            log.warning(Lint.LintCategory.CAST,
+                    tree.pos(), "redundant.cast", tree.expr.type);
+        }
+    }
+    //where
+            private boolean is292targetTypeCast(JCTypeCast tree) {
+                boolean is292targetTypeCast = false;
+                JCExpression expr = TreeInfo.skipParens(tree.expr);
+                if (expr.hasTag(APPLY)) {
+                    JCMethodInvocation apply = (JCMethodInvocation)expr;
+                    Symbol sym = TreeInfo.symbol(apply.meth);
+                    is292targetTypeCast = sym != null &&
+                        sym.kind == MTH &&
+                        (sym.flags() & HYPOTHETICAL) != 0;
+                }
+                return is292targetTypeCast;
+            }
+
+
+
 //where
         /** Is type a type variable, or a (possibly multi-dimensional) array of
          *  type variables?
@@ -838,14 +922,6 @@
                 && types.isSubtype(actual, types.supertype(formal))
                 && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
                 return;
-
-            if (false) {
-                // TODO: make assertConvertible work
-                typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal);
-                throw new AssertionError("Tree: " + tree
-                                         + " actual:" + actual
-                                         + " formal: " + formal);
-            }
         }
 
     /**
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Apr 09 21:58:05 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
 package com.sun.tools.javac.comp;
 
 import java.util.HashMap;
-import java.util.Map;
-import java.util.LinkedHashMap;
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.tree.*;
@@ -179,7 +177,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public class Flow extends TreeScanner {
+public class Flow {
     protected static final Context.Key<Flow> flowKey =
         new Context.Key<Flow>();
 
@@ -202,6 +200,11 @@
         return instance;
     }
 
+    public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
+        new FlowAnalyzer().analyzeTree(env, make);
+        new AssignAnalyzer().analyzeTree(env, make);
+    }
+
     protected Flow(Context context) {
         context.put(flowKey, this);
         names = Names.instance(context);
@@ -216,1268 +219,1572 @@
         allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis();
     }
 
-    /** A flag that indicates whether the last statement could
-     *  complete normally.
+    /**
+     * Base visitor class for all visitors implementing dataflow analysis logic.
+     * This class define the shared logic for handling jumps (break/continue statements).
      */
-    private boolean alive;
+    static abstract class BaseAnalyzer<P extends BaseAnalyzer.PendingExit> extends TreeScanner {
 
-    /** The set of definitely assigned variables.
-     */
-    Bits inits;
+        enum JumpKind {
+            BREAK(JCTree.Tag.BREAK) {
+                @Override
+                JCTree getTarget(JCTree tree) {
+                    return ((JCBreak)tree).target;
+                }
+            },
+            CONTINUE(JCTree.Tag.CONTINUE) {
+                @Override
+                JCTree getTarget(JCTree tree) {
+                    return ((JCContinue)tree).target;
+                }
+            };
 
-    /** The set of definitely unassigned variables.
-     */
-    Bits uninits;
+            JCTree.Tag treeTag;
 
-    HashMap<Symbol, List<Type>> preciseRethrowTypes;
+            private JumpKind(Tag treeTag) {
+                this.treeTag = treeTag;
+            }
 
-    /** The set of variables that are definitely unassigned everywhere
-     *  in current try block. This variable is maintained lazily; it is
-     *  updated only when something gets removed from uninits,
-     *  typically by being assigned in reachable code.  To obtain the
-     *  correct set of variables which are definitely unassigned
-     *  anywhere in current try block, intersect uninitsTry and
-     *  uninits.
-     */
-    Bits uninitsTry;
+            abstract JCTree getTarget(JCTree tree);
+        }
 
-    /** When analyzing a condition, inits and uninits are null.
-     *  Instead we have:
-     */
-    Bits initsWhenTrue;
-    Bits initsWhenFalse;
-    Bits uninitsWhenTrue;
-    Bits uninitsWhenFalse;
+        /** The currently pending exits that go from current inner blocks
+         *  to an enclosing block, in source order.
+         */
+        ListBuffer<P> pendingExits;
 
-    /** A mapping from addresses to variable symbols.
-     */
-    VarSymbol[] vars;
+        /** A pending exit.  These are the statements return, break, and
+         *  continue.  In addition, exception-throwing expressions or
+         *  statements are put here when not known to be caught.  This
+         *  will typically result in an error unless it is within a
+         *  try-finally whose finally block cannot complete normally.
+         */
+        abstract static class PendingExit {
+            JCTree tree;
 
-    /** The current class being defined.
-     */
-    JCClassDecl classDef;
+            PendingExit(JCTree tree) {
+                this.tree = tree;
+            }
 
-    /** The first variable sequence number in this class definition.
-     */
-    int firstadr;
+            abstract void resolveJump();
+        }
 
-    /** The next available variable sequence number.
-     */
-    int nextadr;
+        abstract void markDead();
 
-    /** The list of possibly thrown declarable exceptions.
-     */
-    List<Type> thrown;
+        /** Record an outward transfer of control. */
+        void recordExit(JCTree tree, P pe) {
+            pendingExits.append(pe);
+            markDead();
+        }
 
-    /** The list of exceptions that are either caught or declared to be
-     *  thrown.
-     */
-    List<Type> caught;
+        /** Resolve all jumps of this statement. */
+        private boolean resolveJump(JCTree tree,
+                        ListBuffer<P> oldPendingExits,
+                        JumpKind jk) {
+            boolean resolved = false;
+            List<P> exits = pendingExits.toList();
+            pendingExits = oldPendingExits;
+            for (; exits.nonEmpty(); exits = exits.tail) {
+                P exit = exits.head;
+                if (exit.tree.hasTag(jk.treeTag) &&
+                        jk.getTarget(exit.tree) == tree) {
+                    exit.resolveJump();
+                    resolved = true;
+                } else {
+                    pendingExits.append(exit);
+                }
+            }
+            return resolved;
+        }
 
-    /** The list of unreferenced automatic resources.
-     */
-    Scope unrefdResources;
+        /** Resolve all breaks of this statement. */
+        boolean resolveContinues(JCTree tree) {
+            return resolveJump(tree, new ListBuffer<P>(), JumpKind.CONTINUE);
+        }
 
-    /** Set when processing a loop body the second time for DU analysis. */
-    boolean loopPassTwo = false;
-
-    /*-------------------- Environments ----------------------*/
-
-    /** A pending exit.  These are the statements return, break, and
-     *  continue.  In addition, exception-throwing expressions or
-     *  statements are put here when not known to be caught.  This
-     *  will typically result in an error unless it is within a
-     *  try-finally whose finally block cannot complete normally.
-     */
-    static class PendingExit {
-        JCTree tree;
-        Bits inits;
-        Bits uninits;
-        Type thrown;
-        PendingExit(JCTree tree, Bits inits, Bits uninits) {
-            this.tree = tree;
-            this.inits = inits.dup();
-            this.uninits = uninits.dup();
-        }
-        PendingExit(JCTree tree, Type thrown) {
-            this.tree = tree;
-            this.thrown = thrown;
+        /** Resolve all continues of this statement. */
+        boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) {
+            return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
         }
     }
 
-    /** The currently pending exits that go from current inner blocks
-     *  to an enclosing block, in source order.
+    /**
+     * This pass implements the first two steps of the dataflow analysis:
+     * (i) liveness analysis checks that every statement is reachable and (ii)
+     *  exception analysis to ensure that every checked exception that is
+     *  thrown is declared or caught.
      */
-    ListBuffer<PendingExit> pendingExits;
+    class FlowAnalyzer extends BaseAnalyzer<FlowAnalyzer.FlowPendingExit> {
 
-    /*-------------------- Exceptions ----------------------*/
+        /** A flag that indicates whether the last statement could
+         *  complete normally.
+         */
+        private boolean alive;
 
-    /** Complain that pending exceptions are not caught.
-     */
-    void errorUncaught() {
-        for (PendingExit exit = pendingExits.next();
-             exit != null;
-             exit = pendingExits.next()) {
-            if (classDef != null &&
-                classDef.pos == exit.tree.pos) {
-                log.error(exit.tree.pos(),
-                        "unreported.exception.default.constructor",
-                        exit.thrown);
-            } else if (exit.tree.hasTag(VARDEF) &&
-                    ((JCVariableDecl)exit.tree).sym.isResourceVariable()) {
-                log.error(exit.tree.pos(),
-                        "unreported.exception.implicit.close",
-                        exit.thrown,
-                        ((JCVariableDecl)exit.tree).sym.name);
+        HashMap<Symbol, List<Type>> preciseRethrowTypes;
+
+        /** The current class being defined.
+         */
+        JCClassDecl classDef;
+
+        /** The list of possibly thrown declarable exceptions.
+         */
+        List<Type> thrown;
+
+        /** The list of exceptions that are either caught or declared to be
+         *  thrown.
+         */
+        List<Type> caught;
+
+        class FlowPendingExit extends BaseAnalyzer.PendingExit {
+
+            Type thrown;
+
+            FlowPendingExit(JCTree tree, Type thrown) {
+                super(tree);
+                this.thrown = thrown;
+            }
+
+            void resolveJump() { /*do nothing*/ }
+        }
+
+        @Override
+        void markDead() {
+            alive = false;
+        }
+
+        /*-------------------- Exceptions ----------------------*/
+
+        /** Complain that pending exceptions are not caught.
+         */
+        void errorUncaught() {
+            for (FlowPendingExit exit = pendingExits.next();
+                 exit != null;
+                 exit = pendingExits.next()) {
+                if (classDef != null &&
+                    classDef.pos == exit.tree.pos) {
+                    log.error(exit.tree.pos(),
+                            "unreported.exception.default.constructor",
+                            exit.thrown);
+                } else if (exit.tree.hasTag(VARDEF) &&
+                        ((JCVariableDecl)exit.tree).sym.isResourceVariable()) {
+                    log.error(exit.tree.pos(),
+                            "unreported.exception.implicit.close",
+                            exit.thrown,
+                            ((JCVariableDecl)exit.tree).sym.name);
+                } else {
+                    log.error(exit.tree.pos(),
+                            "unreported.exception.need.to.catch.or.throw",
+                            exit.thrown);
+                }
+            }
+        }
+
+        /** Record that exception is potentially thrown and check that it
+         *  is caught.
+         */
+        void markThrown(JCTree tree, Type exc) {
+            if (!chk.isUnchecked(tree.pos(), exc)) {
+                if (!chk.isHandled(exc, caught))
+                    pendingExits.append(new FlowPendingExit(tree, exc));
+                    thrown = chk.incl(exc, thrown);
+            }
+        }
+
+    /*************************************************************************
+     * Visitor methods for statements and definitions
+     *************************************************************************/
+
+        /** Analyze a definition.
+         */
+        void scanDef(JCTree tree) {
+            scanStat(tree);
+            if (tree != null && tree.hasTag(JCTree.Tag.BLOCK) && !alive) {
+                log.error(tree.pos(),
+                          "initializer.must.be.able.to.complete.normally");
+            }
+        }
+
+        /** Analyze a statement. Check that statement is reachable.
+         */
+        void scanStat(JCTree tree) {
+            if (!alive && tree != null) {
+                log.error(tree.pos(), "unreachable.stmt");
+                if (!tree.hasTag(SKIP)) alive = true;
+            }
+            scan(tree);
+        }
+
+        /** Analyze list of statements.
+         */
+        void scanStats(List<? extends JCStatement> trees) {
+            if (trees != null)
+                for (List<? extends JCStatement> l = trees; l.nonEmpty(); l = l.tail)
+                    scanStat(l.head);
+        }
+
+        /* ------------ Visitor methods for various sorts of trees -------------*/
+
+        public void visitClassDef(JCClassDecl tree) {
+            if (tree.sym == null) return;
+
+            JCClassDecl classDefPrev = classDef;
+            List<Type> thrownPrev = thrown;
+            List<Type> caughtPrev = caught;
+            boolean alivePrev = alive;
+            ListBuffer<FlowPendingExit> pendingExitsPrev = pendingExits;
+            Lint lintPrev = lint;
+
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            if (tree.name != names.empty) {
+                caught = List.nil();
+            }
+            classDef = tree;
+            thrown = List.nil();
+            lint = lint.augment(tree.sym.attributes_field);
+
+            try {
+                // process all the static initializers
+                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                    if (!l.head.hasTag(METHODDEF) &&
+                        (TreeInfo.flags(l.head) & STATIC) != 0) {
+                        scanDef(l.head);
+                        errorUncaught();
+                    }
+                }
+
+                // add intersection of all thrown clauses of initial constructors
+                // to set of caught exceptions, unless class is anonymous.
+                if (tree.name != names.empty) {
+                    boolean firstConstructor = true;
+                    for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                        if (TreeInfo.isInitialConstructor(l.head)) {
+                            List<Type> mthrown =
+                                ((JCMethodDecl) l.head).sym.type.getThrownTypes();
+                            if (firstConstructor) {
+                                caught = mthrown;
+                                firstConstructor = false;
+                            } else {
+                                caught = chk.intersect(mthrown, caught);
+                            }
+                        }
+                    }
+                }
+
+                // process all the instance initializers
+                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                    if (!l.head.hasTag(METHODDEF) &&
+                        (TreeInfo.flags(l.head) & STATIC) == 0) {
+                        scanDef(l.head);
+                        errorUncaught();
+                    }
+                }
+
+                // in an anonymous class, add the set of thrown exceptions to
+                // the throws clause of the synthetic constructor and propagate
+                // outwards.
+                // Changing the throws clause on the fly is okay here because
+                // the anonymous constructor can't be invoked anywhere else,
+                // and its type hasn't been cached.
+                if (tree.name == names.empty) {
+                    for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                        if (TreeInfo.isInitialConstructor(l.head)) {
+                            JCMethodDecl mdef = (JCMethodDecl)l.head;
+                            mdef.thrown = make.Types(thrown);
+                            mdef.sym.type = types.createMethodTypeWithThrown(mdef.sym.type, thrown);
+                        }
+                    }
+                    thrownPrev = chk.union(thrown, thrownPrev);
+                }
+
+                // process all the methods
+                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                    if (l.head.hasTag(METHODDEF)) {
+                        scan(l.head);
+                        errorUncaught();
+                    }
+                }
+
+                thrown = thrownPrev;
+            } finally {
+                pendingExits = pendingExitsPrev;
+                alive = alivePrev;
+                caught = caughtPrev;
+                classDef = classDefPrev;
+                lint = lintPrev;
+            }
+        }
+
+        public void visitMethodDef(JCMethodDecl tree) {
+            if (tree.body == null) return;
+
+            List<Type> caughtPrev = caught;
+            List<Type> mthrown = tree.sym.type.getThrownTypes();
+            Lint lintPrev = lint;
+
+            lint = lint.augment(tree.sym.attributes_field);
+
+            Assert.check(pendingExits.isEmpty());
+
+            try {
+                for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
+                    JCVariableDecl def = l.head;
+                    scan(def);
+                }
+                if (TreeInfo.isInitialConstructor(tree))
+                    caught = chk.union(caught, mthrown);
+                else if ((tree.sym.flags() & (BLOCK | STATIC)) != BLOCK)
+                    caught = mthrown;
+                // else we are in an instance initializer block;
+                // leave caught unchanged.
+
+                alive = true;
+                scanStat(tree.body);
+
+                if (alive && tree.sym.type.getReturnType().tag != VOID)
+                    log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
+
+                List<FlowPendingExit> exits = pendingExits.toList();
+                pendingExits = new ListBuffer<FlowPendingExit>();
+                while (exits.nonEmpty()) {
+                    FlowPendingExit exit = exits.head;
+                    exits = exits.tail;
+                    if (exit.thrown == null) {
+                        Assert.check(exit.tree.hasTag(RETURN));
+                    } else {
+                        // uncaught throws will be reported later
+                        pendingExits.append(exit);
+                    }
+                }
+            } finally {
+                caught = caughtPrev;
+                lint = lintPrev;
+            }
+        }
+
+        public void visitVarDef(JCVariableDecl tree) {
+            if (tree.init != null) {
+                Lint lintPrev = lint;
+                lint = lint.augment(tree.sym.attributes_field);
+                try{
+                    scan(tree.init);
+                } finally {
+                    lint = lintPrev;
+                }
+            }
+        }
+
+        public void visitBlock(JCBlock tree) {
+            scanStats(tree.stats);
+        }
+
+        public void visitDoLoop(JCDoWhileLoop tree) {
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            scanStat(tree.body);
+            alive |= resolveContinues(tree);
+            scan(tree.cond);
+            alive = alive && !tree.cond.type.isTrue();
+            alive |= resolveBreaks(tree, prevPendingExits);
+        }
+
+        public void visitWhileLoop(JCWhileLoop tree) {
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            scan(tree.cond);
+            alive = !tree.cond.type.isFalse();
+            scanStat(tree.body);
+            alive |= resolveContinues(tree);
+            alive = resolveBreaks(tree, prevPendingExits) ||
+                !tree.cond.type.isTrue();
+        }
+
+        public void visitForLoop(JCForLoop tree) {
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            scanStats(tree.init);
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            if (tree.cond != null) {
+                scan(tree.cond);
+                alive = !tree.cond.type.isFalse();
             } else {
-                log.error(exit.tree.pos(),
-                        "unreported.exception.need.to.catch.or.throw",
-                        exit.thrown);
+                alive = true;
+            }
+            scanStat(tree.body);
+            alive |= resolveContinues(tree);
+            scan(tree.step);
+            alive = resolveBreaks(tree, prevPendingExits) ||
+                tree.cond != null && !tree.cond.type.isTrue();
+        }
+
+        public void visitForeachLoop(JCEnhancedForLoop tree) {
+            visitVarDef(tree.var);
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            scan(tree.expr);
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            scanStat(tree.body);
+            alive |= resolveContinues(tree);
+            resolveBreaks(tree, prevPendingExits);
+            alive = true;
+        }
+
+        public void visitLabelled(JCLabeledStatement tree) {
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            scanStat(tree.body);
+            alive |= resolveBreaks(tree, prevPendingExits);
+        }
+
+        public void visitSwitch(JCSwitch tree) {
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            scan(tree.selector);
+            boolean hasDefault = false;
+            for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
+                alive = true;
+                JCCase c = l.head;
+                if (c.pat == null)
+                    hasDefault = true;
+                else
+                    scan(c.pat);
+                scanStats(c.stats);
+                // Warn about fall-through if lint switch fallthrough enabled.
+                if (alive &&
+                    lint.isEnabled(Lint.LintCategory.FALLTHROUGH) &&
+                    c.stats.nonEmpty() && l.tail.nonEmpty())
+                    log.warning(Lint.LintCategory.FALLTHROUGH,
+                                l.tail.head.pos(),
+                                "possible.fall-through.into.case");
+            }
+            if (!hasDefault) {
+                alive = true;
+            }
+            alive |= resolveBreaks(tree, prevPendingExits);
+        }
+
+        public void visitTry(JCTry tree) {
+            List<Type> caughtPrev = caught;
+            List<Type> thrownPrev = thrown;
+            thrown = List.nil();
+            for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
+                List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
+                        ((JCTypeUnion)l.head.param.vartype).alternatives :
+                        List.of(l.head.param.vartype);
+                for (JCExpression ct : subClauses) {
+                    caught = chk.incl(ct.type, caught);
+                }
+            }
+
+            ListBuffer<FlowPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<FlowPendingExit>();
+            for (JCTree resource : tree.resources) {
+                if (resource instanceof JCVariableDecl) {
+                    JCVariableDecl vdecl = (JCVariableDecl) resource;
+                    visitVarDef(vdecl);
+                } else if (resource instanceof JCExpression) {
+                    scan((JCExpression) resource);
+                } else {
+                    throw new AssertionError(tree);  // parser error
+                }
+            }
+            for (JCTree resource : tree.resources) {
+                List<Type> closeableSupertypes = resource.type.isCompound() ?
+                    types.interfaces(resource.type).prepend(types.supertype(resource.type)) :
+                    List.of(resource.type);
+                for (Type sup : closeableSupertypes) {
+                    if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) {
+                        Symbol closeMethod = rs.resolveQualifiedMethod(tree,
+                                attrEnv,
+                                sup,
+                                names.close,
+                                List.<Type>nil(),
+                                List.<Type>nil());
+                        if (closeMethod.kind == MTH) {
+                            for (Type t : ((MethodSymbol)closeMethod).getThrownTypes()) {
+                                markThrown(resource, t);
+                            }
+                        }
+                    }
+                }
+            }
+            scanStat(tree.body);
+            List<Type> thrownInTry = allowImprovedCatchAnalysis ?
+                chk.union(thrown, List.of(syms.runtimeExceptionType, syms.errorType)) :
+                thrown;
+            thrown = thrownPrev;
+            caught = caughtPrev;
+            boolean aliveEnd = alive;
+
+            List<Type> caughtInTry = List.nil();
+            for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
+                alive = true;
+                JCVariableDecl param = l.head.param;
+                List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
+                        ((JCTypeUnion)l.head.param.vartype).alternatives :
+                        List.of(l.head.param.vartype);
+                List<Type> ctypes = List.nil();
+                List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
+                for (JCExpression ct : subClauses) {
+                    Type exc = ct.type;
+                    if (exc != syms.unknownType) {
+                        ctypes = ctypes.append(exc);
+                        if (types.isSameType(exc, syms.objectType))
+                            continue;
+                        checkCaughtType(l.head.pos(), exc, thrownInTry, caughtInTry);
+                        caughtInTry = chk.incl(exc, caughtInTry);
+                    }
+                }
+                scan(param);
+                preciseRethrowTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
+                scanStat(l.head.body);
+                preciseRethrowTypes.remove(param.sym);
+                aliveEnd |= alive;
+            }
+            if (tree.finalizer != null) {
+                List<Type> savedThrown = thrown;
+                thrown = List.nil();
+                ListBuffer<FlowPendingExit> exits = pendingExits;
+                pendingExits = prevPendingExits;
+                alive = true;
+                scanStat(tree.finalizer);
+                if (!alive) {
+                    // discard exits and exceptions from try and finally
+                    thrown = chk.union(thrown, thrownPrev);
+                    if (lint.isEnabled(Lint.LintCategory.FINALLY)) {
+                        log.warning(Lint.LintCategory.FINALLY,
+                                TreeInfo.diagEndPos(tree.finalizer),
+                                "finally.cannot.complete");
+                    }
+                } else {
+                    thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
+                    thrown = chk.union(thrown, savedThrown);
+                    // FIX: this doesn't preserve source order of exits in catch
+                    // versus finally!
+                    while (exits.nonEmpty()) {
+                        pendingExits.append(exits.next());
+                    }
+                    alive = aliveEnd;
+                }
+                tree.finallyCanCompleteNormally = alive;
+            } else {
+                thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
+                alive = aliveEnd;
+                ListBuffer<FlowPendingExit> exits = pendingExits;
+                pendingExits = prevPendingExits;
+                while (exits.nonEmpty()) pendingExits.append(exits.next());
+            }
+        }
+
+        @Override
+        public void visitIf(JCIf tree) {
+            scan(tree.cond);
+            scanStat(tree.thenpart);
+            if (tree.elsepart != null) {
+                boolean aliveAfterThen = alive;
+                alive = true;
+                scanStat(tree.elsepart);
+                alive = alive | aliveAfterThen;
+            } else {
+                alive = true;
+            }
+        }
+
+        void checkCaughtType(DiagnosticPosition pos, Type exc, List<Type> thrownInTry, List<Type> caughtInTry) {
+            if (chk.subset(exc, caughtInTry)) {
+                log.error(pos, "except.already.caught", exc);
+            } else if (!chk.isUnchecked(pos, exc) &&
+                    !isExceptionOrThrowable(exc) &&
+                    !chk.intersects(exc, thrownInTry)) {
+                log.error(pos, "except.never.thrown.in.try", exc);
+            } else if (allowImprovedCatchAnalysis) {
+                List<Type> catchableThrownTypes = chk.intersect(List.of(exc), thrownInTry);
+                // 'catchableThrownTypes' cannnot possibly be empty - if 'exc' was an
+                // unchecked exception, the result list would not be empty, as the augmented
+                // thrown set includes { RuntimeException, Error }; if 'exc' was a checked
+                // exception, that would have been covered in the branch above
+                if (chk.diff(catchableThrownTypes, caughtInTry).isEmpty() &&
+                        !isExceptionOrThrowable(exc)) {
+                    String key = catchableThrownTypes.length() == 1 ?
+                            "unreachable.catch" :
+                            "unreachable.catch.1";
+                    log.warning(pos, key, catchableThrownTypes);
+                }
+            }
+        }
+        //where
+            private boolean isExceptionOrThrowable(Type exc) {
+                return exc.tsym == syms.throwableType.tsym ||
+                    exc.tsym == syms.exceptionType.tsym;
+            }
+
+        public void visitBreak(JCBreak tree) {
+            recordExit(tree, new FlowPendingExit(tree, null));
+        }
+
+        public void visitContinue(JCContinue tree) {
+            recordExit(tree, new FlowPendingExit(tree, null));
+        }
+
+        public void visitReturn(JCReturn tree) {
+            scan(tree.expr);
+            // if not initial constructor, should markDead instead of recordExit
+            recordExit(tree, new FlowPendingExit(tree, null));
+        }
+
+        public void visitThrow(JCThrow tree) {
+            scan(tree.expr);
+            Symbol sym = TreeInfo.symbol(tree.expr);
+            if (sym != null &&
+                sym.kind == VAR &&
+                (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 &&
+                preciseRethrowTypes.get(sym) != null &&
+                allowImprovedRethrowAnalysis) {
+                for (Type t : preciseRethrowTypes.get(sym)) {
+                    markThrown(tree, t);
+                }
+            }
+            else {
+                markThrown(tree, tree.expr.type);
+            }
+            markDead();
+        }
+
+        public void visitApply(JCMethodInvocation tree) {
+            scan(tree.meth);
+            scan(tree.args);
+            for (List<Type> l = tree.meth.type.getThrownTypes(); l.nonEmpty(); l = l.tail)
+                markThrown(tree, l.head);
+        }
+
+        public void visitNewClass(JCNewClass tree) {
+            scan(tree.encl);
+            scan(tree.args);
+           // scan(tree.def);
+            for (List<Type> l = tree.constructorType.getThrownTypes();
+                 l.nonEmpty();
+                 l = l.tail) {
+                markThrown(tree, l.head);
+            }
+            List<Type> caughtPrev = caught;
+            try {
+                // If the new class expression defines an anonymous class,
+                // analysis of the anonymous constructor may encounter thrown
+                // types which are unsubstituted type variables.
+                // However, since the constructor's actual thrown types have
+                // already been marked as thrown, it is safe to simply include
+                // each of the constructor's formal thrown types in the set of
+                // 'caught/declared to be thrown' types, for the duration of
+                // the class def analysis.
+                if (tree.def != null)
+                    for (List<Type> l = tree.constructor.type.getThrownTypes();
+                         l.nonEmpty();
+                         l = l.tail) {
+                        caught = chk.incl(l.head, caught);
+                    }
+                scan(tree.def);
+            }
+            finally {
+                caught = caughtPrev;
+            }
+        }
+
+        public void visitTopLevel(JCCompilationUnit tree) {
+            // Do nothing for TopLevel since each class is visited individually
+        }
+
+    /**************************************************************************
+     * main method
+     *************************************************************************/
+
+        /** Perform definite assignment/unassignment analysis on a tree.
+         */
+        public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
+            try {
+                attrEnv = env;
+                JCTree tree = env.tree;
+                Flow.this.make = make;
+                pendingExits = new ListBuffer<FlowPendingExit>();
+                preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
+                alive = true;
+                this.thrown = this.caught = null;
+                this.classDef = null;
+                scan(tree);
+            } finally {
+                pendingExits = null;
+                Flow.this.make = null;
+                this.thrown = this.caught = null;
+                this.classDef = null;
             }
         }
     }
 
-    /** Record that exception is potentially thrown and check that it
-     *  is caught.
+    /**
+     * This pass implements (i) definite assignment analysis, which ensures that
+     * each variable is assigned when used and (ii) definite unassignment analysis,
+     * which ensures that no final variable is assigned more than once. This visitor
+     * depends on the results of the liveliness analyzer.
      */
-    void markThrown(JCTree tree, Type exc) {
-        if (!chk.isUnchecked(tree.pos(), exc)) {
-            if (!chk.isHandled(exc, caught))
-                pendingExits.append(new PendingExit(tree, exc));
-                thrown = chk.incl(exc, thrown);
+    class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> {
+
+        /** The set of definitely assigned variables.
+         */
+        Bits inits;
+
+        /** The set of definitely unassigned variables.
+         */
+        Bits uninits;
+
+        /** The set of variables that are definitely unassigned everywhere
+         *  in current try block. This variable is maintained lazily; it is
+         *  updated only when something gets removed from uninits,
+         *  typically by being assigned in reachable code.  To obtain the
+         *  correct set of variables which are definitely unassigned
+         *  anywhere in current try block, intersect uninitsTry and
+         *  uninits.
+         */
+        Bits uninitsTry;
+
+        /** When analyzing a condition, inits and uninits are null.
+         *  Instead we have:
+         */
+        Bits initsWhenTrue;
+        Bits initsWhenFalse;
+        Bits uninitsWhenTrue;
+        Bits uninitsWhenFalse;
+
+        /** A mapping from addresses to variable symbols.
+         */
+        VarSymbol[] vars;
+
+        /** The current class being defined.
+         */
+        JCClassDecl classDef;
+
+        /** The first variable sequence number in this class definition.
+         */
+        int firstadr;
+
+        /** The next available variable sequence number.
+         */
+        int nextadr;
+
+        /** The list of unreferenced automatic resources.
+         */
+        Scope unrefdResources;
+
+        /** Set when processing a loop body the second time for DU analysis. */
+        boolean loopPassTwo = false;
+
+        class AssignPendingExit extends BaseAnalyzer.PendingExit {
+
+            Bits exit_inits;
+            Bits exit_uninits;
+
+            AssignPendingExit(JCTree tree, Bits inits, Bits uninits) {
+                super(tree);
+                this.exit_inits = inits.dup();
+                this.exit_uninits = uninits.dup();
+            }
+
+            void resolveJump() {
+                inits.andSet(exit_inits);
+                uninits.andSet(exit_uninits);
+            }
         }
-    }
 
-    /*-------------- Processing variables ----------------------*/
+        @Override
+        void markDead() {
+            inits.inclRange(firstadr, nextadr);
+            uninits.inclRange(firstadr, nextadr);
+        }
 
-    /** Do we need to track init/uninit state of this symbol?
-     *  I.e. is symbol either a local or a blank final variable?
-     */
-    boolean trackable(VarSymbol sym) {
-        return
-            (sym.owner.kind == MTH ||
-             ((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL &&
-              classDef.sym.isEnclosedBy((ClassSymbol)sym.owner)));
-    }
+        /*-------------- Processing variables ----------------------*/
 
-    /** Initialize new trackable variable by setting its address field
-     *  to the next available sequence number and entering it under that
-     *  index into the vars array.
-     */
-    void newVar(VarSymbol sym) {
-        if (nextadr == vars.length) {
-            VarSymbol[] newvars = new VarSymbol[nextadr * 2];
-            System.arraycopy(vars, 0, newvars, 0, nextadr);
-            vars = newvars;
+        /** Do we need to track init/uninit state of this symbol?
+         *  I.e. is symbol either a local or a blank final variable?
+         */
+        boolean trackable(VarSymbol sym) {
+            return
+                (sym.owner.kind == MTH ||
+                 ((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL &&
+                  classDef.sym.isEnclosedBy((ClassSymbol)sym.owner)));
         }
-        sym.adr = nextadr;
-        vars[nextadr] = sym;
-        inits.excl(nextadr);
-        uninits.incl(nextadr);
-        nextadr++;
-    }
 
-    /** Record an initialization of a trackable variable.
-     */
-    void letInit(DiagnosticPosition pos, VarSymbol sym) {
-        if (sym.adr >= firstadr && trackable(sym)) {
-            if ((sym.flags() & FINAL) != 0) {
-                if ((sym.flags() & PARAMETER) != 0) {
-                    if ((sym.flags() & UNION) != 0) { //multi-catch parameter
-                        log.error(pos, "multicatch.parameter.may.not.be.assigned",
+        /** Initialize new trackable variable by setting its address field
+         *  to the next available sequence number and entering it under that
+         *  index into the vars array.
+         */
+        void newVar(VarSymbol sym) {
+            if (nextadr == vars.length) {
+                VarSymbol[] newvars = new VarSymbol[nextadr * 2];
+                System.arraycopy(vars, 0, newvars, 0, nextadr);
+                vars = newvars;
+            }
+            sym.adr = nextadr;
+            vars[nextadr] = sym;
+            inits.excl(nextadr);
+            uninits.incl(nextadr);
+            nextadr++;
+        }
+
+        /** Record an initialization of a trackable variable.
+         */
+        void letInit(DiagnosticPosition pos, VarSymbol sym) {
+            if (sym.adr >= firstadr && trackable(sym)) {
+                if ((sym.flags() & FINAL) != 0) {
+                    if ((sym.flags() & PARAMETER) != 0) {
+                        if ((sym.flags() & UNION) != 0) { //multi-catch parameter
+                            log.error(pos, "multicatch.parameter.may.not.be.assigned",
+                                      sym);
+                        }
+                        else {
+                            log.error(pos, "final.parameter.may.not.be.assigned",
                                   sym);
+                        }
+                    } else if (!uninits.isMember(sym.adr)) {
+                        log.error(pos,
+                                  loopPassTwo
+                                  ? "var.might.be.assigned.in.loop"
+                                  : "var.might.already.be.assigned",
+                                  sym);
+                    } else if (!inits.isMember(sym.adr)) {
+                        // reachable assignment
+                        uninits.excl(sym.adr);
+                        uninitsTry.excl(sym.adr);
+                    } else {
+                        //log.rawWarning(pos, "unreachable assignment");//DEBUG
+                        uninits.excl(sym.adr);
                     }
-                    else {
-                        log.error(pos, "final.parameter.may.not.be.assigned",
-                              sym);
-                    }
-                } else if (!uninits.isMember(sym.adr)) {
-                    log.error(pos,
-                              loopPassTwo
-                              ? "var.might.be.assigned.in.loop"
-                              : "var.might.already.be.assigned",
-                              sym);
-                } else if (!inits.isMember(sym.adr)) {
-                    // reachable assignment
-                    uninits.excl(sym.adr);
-                    uninitsTry.excl(sym.adr);
-                } else {
-                    //log.rawWarning(pos, "unreachable assignment");//DEBUG
-                    uninits.excl(sym.adr);
+                }
+                inits.incl(sym.adr);
+            } else if ((sym.flags() & FINAL) != 0) {
+                log.error(pos, "var.might.already.be.assigned", sym);
+            }
+        }
+
+        /** If tree is either a simple name or of the form this.name or
+         *  C.this.name, and tree represents a trackable variable,
+         *  record an initialization of the variable.
+         */
+        void letInit(JCTree tree) {
+            tree = TreeInfo.skipParens(tree);
+            if (tree.hasTag(IDENT) || tree.hasTag(SELECT)) {
+                Symbol sym = TreeInfo.symbol(tree);
+                if (sym.kind == VAR) {
+                    letInit(tree.pos(), (VarSymbol)sym);
                 }
             }
-            inits.incl(sym.adr);
-        } else if ((sym.flags() & FINAL) != 0) {
-            log.error(pos, "var.might.already.be.assigned", sym);
         }
-    }
 
-    /** If tree is either a simple name or of the form this.name or
-     *  C.this.name, and tree represents a trackable variable,
-     *  record an initialization of the variable.
-     */
-    void letInit(JCTree tree) {
-        tree = TreeInfo.skipParens(tree);
-        if (tree.hasTag(IDENT) || tree.hasTag(SELECT)) {
-            Symbol sym = TreeInfo.symbol(tree);
-            if (sym.kind == VAR) {
-                letInit(tree.pos(), (VarSymbol)sym);
+        /** Check that trackable variable is initialized.
+         */
+        void checkInit(DiagnosticPosition pos, VarSymbol sym) {
+            if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
+                trackable(sym) &&
+                !inits.isMember(sym.adr)) {
+                log.error(pos, "var.might.not.have.been.initialized",
+                          sym);
+                inits.incl(sym.adr);
             }
         }
-    }
 
-    /** Check that trackable variable is initialized.
-     */
-    void checkInit(DiagnosticPosition pos, VarSymbol sym) {
-        if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
-            trackable(sym) &&
-            !inits.isMember(sym.adr)) {
-            log.error(pos, "var.might.not.have.been.initialized",
-                      sym);
-            inits.incl(sym.adr);
+        /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
+         */
+        void split(boolean setToNull) {
+            initsWhenFalse = inits.dup();
+            uninitsWhenFalse = uninits.dup();
+            initsWhenTrue = inits;
+            uninitsWhenTrue = uninits;
+            if (setToNull)
+                inits = uninits = null;
         }
-    }
 
-    /*-------------------- Handling jumps ----------------------*/
+        /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
+         */
+        void merge() {
+            inits = initsWhenFalse.andSet(initsWhenTrue);
+            uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
+        }
 
-    /** Record an outward transfer of control. */
-    void recordExit(JCTree tree) {
-        pendingExits.append(new PendingExit(tree, inits, uninits));
-        markDead();
-    }
+    /* ************************************************************************
+     * Visitor methods for statements and definitions
+     *************************************************************************/
 
-    /** Resolve all breaks of this statement. */
-    boolean resolveBreaks(JCTree tree,
-                          ListBuffer<PendingExit> oldPendingExits) {
-        boolean result = false;
-        List<PendingExit> exits = pendingExits.toList();
-        pendingExits = oldPendingExits;
-        for (; exits.nonEmpty(); exits = exits.tail) {
-            PendingExit exit = exits.head;
-            if (exit.tree.hasTag(BREAK) &&
-                ((JCBreak) exit.tree).target == tree) {
-                inits.andSet(exit.inits);
-                uninits.andSet(exit.uninits);
-                result = true;
-            } else {
-                pendingExits.append(exit);
+        /** Analyze an expression. Make sure to set (un)inits rather than
+         *  (un)initsWhenTrue(WhenFalse) on exit.
+         */
+        void scanExpr(JCTree tree) {
+            if (tree != null) {
+                scan(tree);
+                if (inits == null) merge();
             }
         }
-        return result;
-    }
 
-    /** Resolve all continues of this statement. */
-    boolean resolveContinues(JCTree tree) {
-        boolean result = false;
-        List<PendingExit> exits = pendingExits.toList();
-        pendingExits = new ListBuffer<PendingExit>();
-        for (; exits.nonEmpty(); exits = exits.tail) {
-            PendingExit exit = exits.head;
-            if (exit.tree.hasTag(CONTINUE) &&
-                ((JCContinue) exit.tree).target == tree) {
-                inits.andSet(exit.inits);
-                uninits.andSet(exit.uninits);
-                result = true;
+        /** Analyze a list of expressions.
+         */
+        void scanExprs(List<? extends JCExpression> trees) {
+            if (trees != null)
+                for (List<? extends JCExpression> l = trees; l.nonEmpty(); l = l.tail)
+                    scanExpr(l.head);
+        }
+
+        /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse)
+         *  rather than (un)inits on exit.
+         */
+        void scanCond(JCTree tree) {
+            if (tree.type.isFalse()) {
+                if (inits == null) merge();
+                initsWhenTrue = inits.dup();
+                initsWhenTrue.inclRange(firstadr, nextadr);
+                uninitsWhenTrue = uninits.dup();
+                uninitsWhenTrue.inclRange(firstadr, nextadr);
+                initsWhenFalse = inits;
+                uninitsWhenFalse = uninits;
+            } else if (tree.type.isTrue()) {
+                if (inits == null) merge();
+                initsWhenFalse = inits.dup();
+                initsWhenFalse.inclRange(firstadr, nextadr);
+                uninitsWhenFalse = uninits.dup();
+                uninitsWhenFalse.inclRange(firstadr, nextadr);
+                initsWhenTrue = inits;
+                uninitsWhenTrue = uninits;
             } else {
-                pendingExits.append(exit);
+                scan(tree);
+                if (inits != null)
+                    split(tree.type != syms.unknownType);
             }
+            if (tree.type != syms.unknownType)
+                inits = uninits = null;
         }
-        return result;
-    }
 
-    /** Record that statement is unreachable.
-     */
-    void markDead() {
-        inits.inclRange(firstadr, nextadr);
-        uninits.inclRange(firstadr, nextadr);
-        alive = false;
-    }
+        /* ------------ Visitor methods for various sorts of trees -------------*/
 
-    /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
-     */
-    void split(boolean setToNull) {
-        initsWhenFalse = inits.dup();
-        uninitsWhenFalse = uninits.dup();
-        initsWhenTrue = inits;
-        uninitsWhenTrue = uninits;
-        if (setToNull)
-            inits = uninits = null;
-    }
+        public void visitClassDef(JCClassDecl tree) {
+            if (tree.sym == null) return;
 
-    /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
-     */
-    void merge() {
-        inits = initsWhenFalse.andSet(initsWhenTrue);
-        uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
-    }
+            JCClassDecl classDefPrev = classDef;
+            int firstadrPrev = firstadr;
+            int nextadrPrev = nextadr;
+            ListBuffer<AssignPendingExit> pendingExitsPrev = pendingExits;
+            Lint lintPrev = lint;
 
-/* ************************************************************************
- * Visitor methods for statements and definitions
- *************************************************************************/
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            if (tree.name != names.empty) {
+                firstadr = nextadr;
+            }
+            classDef = tree;
+            lint = lint.augment(tree.sym.attributes_field);
 
-    /** Analyze a definition.
-     */
-    void scanDef(JCTree tree) {
-        scanStat(tree);
-        if (tree != null && tree.hasTag(JCTree.Tag.BLOCK) && !alive) {
-            log.error(tree.pos(),
-                      "initializer.must.be.able.to.complete.normally");
-        }
-    }
-
-    /** Analyze a statement. Check that statement is reachable.
-     */
-    void scanStat(JCTree tree) {
-        if (!alive && tree != null) {
-            log.error(tree.pos(), "unreachable.stmt");
-            if (!tree.hasTag(SKIP)) alive = true;
-        }
-        scan(tree);
-    }
-
-    /** Analyze list of statements.
-     */
-    void scanStats(List<? extends JCStatement> trees) {
-        if (trees != null)
-            for (List<? extends JCStatement> l = trees; l.nonEmpty(); l = l.tail)
-                scanStat(l.head);
-    }
-
-    /** Analyze an expression. Make sure to set (un)inits rather than
-     *  (un)initsWhenTrue(WhenFalse) on exit.
-     */
-    void scanExpr(JCTree tree) {
-        if (tree != null) {
-            scan(tree);
-            if (inits == null) merge();
-        }
-    }
-
-    /** Analyze a list of expressions.
-     */
-    void scanExprs(List<? extends JCExpression> trees) {
-        if (trees != null)
-            for (List<? extends JCExpression> l = trees; l.nonEmpty(); l = l.tail)
-                scanExpr(l.head);
-    }
-
-    /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse)
-     *  rather than (un)inits on exit.
-     */
-    void scanCond(JCTree tree) {
-        if (tree.type.isFalse()) {
-            if (inits == null) merge();
-            initsWhenTrue = inits.dup();
-            initsWhenTrue.inclRange(firstadr, nextadr);
-            uninitsWhenTrue = uninits.dup();
-            uninitsWhenTrue.inclRange(firstadr, nextadr);
-            initsWhenFalse = inits;
-            uninitsWhenFalse = uninits;
-        } else if (tree.type.isTrue()) {
-            if (inits == null) merge();
-            initsWhenFalse = inits.dup();
-            initsWhenFalse.inclRange(firstadr, nextadr);
-            uninitsWhenFalse = uninits.dup();
-            uninitsWhenFalse.inclRange(firstadr, nextadr);
-            initsWhenTrue = inits;
-            uninitsWhenTrue = uninits;
-        } else {
-            scan(tree);
-            if (inits != null)
-                split(tree.type != syms.unknownType);
-        }
-        if (tree.type != syms.unknownType)
-            inits = uninits = null;
-    }
-
-    /* ------------ Visitor methods for various sorts of trees -------------*/
-
-    public void visitClassDef(JCClassDecl tree) {
-        if (tree.sym == null) return;
-
-        JCClassDecl classDefPrev = classDef;
-        List<Type> thrownPrev = thrown;
-        List<Type> caughtPrev = caught;
-        boolean alivePrev = alive;
-        int firstadrPrev = firstadr;
-        int nextadrPrev = nextadr;
-        ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
-        Lint lintPrev = lint;
-
-        pendingExits = new ListBuffer<PendingExit>();
-        if (tree.name != names.empty) {
-            caught = List.nil();
-            firstadr = nextadr;
-        }
-        classDef = tree;
-        thrown = List.nil();
-        lint = lint.augment(tree.sym.attributes_field);
-
-        try {
-            // define all the static fields
-            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                if (l.head.hasTag(VARDEF)) {
-                    JCVariableDecl def = (JCVariableDecl)l.head;
-                    if ((def.mods.flags & STATIC) != 0) {
-                        VarSymbol sym = def.sym;
-                        if (trackable(sym))
-                            newVar(sym);
-                    }
-                }
-            }
-
-            // process all the static initializers
-            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                if (!l.head.hasTag(METHODDEF) &&
-                    (TreeInfo.flags(l.head) & STATIC) != 0) {
-                    scanDef(l.head);
-                    errorUncaught();
-                }
-            }
-
-            // add intersection of all thrown clauses of initial constructors
-            // to set of caught exceptions, unless class is anonymous.
-            if (tree.name != names.empty) {
-                boolean firstConstructor = true;
+            try {
+                // define all the static fields
                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                    if (TreeInfo.isInitialConstructor(l.head)) {
-                        List<Type> mthrown =
-                            ((JCMethodDecl) l.head).sym.type.getThrownTypes();
-                        if (firstConstructor) {
-                            caught = mthrown;
-                            firstConstructor = false;
-                        } else {
-                            caught = chk.intersect(mthrown, caught);
+                    if (l.head.hasTag(VARDEF)) {
+                        JCVariableDecl def = (JCVariableDecl)l.head;
+                        if ((def.mods.flags & STATIC) != 0) {
+                            VarSymbol sym = def.sym;
+                            if (trackable(sym))
+                                newVar(sym);
                         }
                     }
                 }
-            }
 
-            // define all the instance fields
-            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                if (l.head.hasTag(VARDEF)) {
-                    JCVariableDecl def = (JCVariableDecl)l.head;
-                    if ((def.mods.flags & STATIC) == 0) {
-                        VarSymbol sym = def.sym;
-                        if (trackable(sym))
-                            newVar(sym);
+                // process all the static initializers
+                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                    if (!l.head.hasTag(METHODDEF) &&
+                        (TreeInfo.flags(l.head) & STATIC) != 0) {
+                        scan(l.head);
                     }
                 }
-            }
 
-            // process all the instance initializers
-            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                if (!l.head.hasTag(METHODDEF) &&
-                    (TreeInfo.flags(l.head) & STATIC) == 0) {
-                    scanDef(l.head);
-                    errorUncaught();
-                }
-            }
-
-            // in an anonymous class, add the set of thrown exceptions to
-            // the throws clause of the synthetic constructor and propagate
-            // outwards.
-            // Changing the throws clause on the fly is okay here because
-            // the anonymous constructor can't be invoked anywhere else,
-            // and its type hasn't been cached.
-            if (tree.name == names.empty) {
+                // define all the instance fields
                 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                    if (TreeInfo.isInitialConstructor(l.head)) {
-                        JCMethodDecl mdef = (JCMethodDecl)l.head;
-                        mdef.thrown = make.Types(thrown);
-                        mdef.sym.type = types.createMethodTypeWithThrown(mdef.sym.type, thrown);
+                    if (l.head.hasTag(VARDEF)) {
+                        JCVariableDecl def = (JCVariableDecl)l.head;
+                        if ((def.mods.flags & STATIC) == 0) {
+                            VarSymbol sym = def.sym;
+                            if (trackable(sym))
+                                newVar(sym);
+                        }
                     }
                 }
-                thrownPrev = chk.union(thrown, thrownPrev);
+
+                // process all the instance initializers
+                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                    if (!l.head.hasTag(METHODDEF) &&
+                        (TreeInfo.flags(l.head) & STATIC) == 0) {
+                        scan(l.head);
+                    }
+                }
+
+                // process all the methods
+                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                    if (l.head.hasTag(METHODDEF)) {
+                        scan(l.head);
+                    }
+                }
+            } finally {
+                pendingExits = pendingExitsPrev;
+                nextadr = nextadrPrev;
+                firstadr = firstadrPrev;
+                classDef = classDefPrev;
+                lint = lintPrev;
             }
+        }
 
-            // process all the methods
-            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
-                if (l.head.hasTag(METHODDEF)) {
-                    scan(l.head);
-                    errorUncaught();
+        public void visitMethodDef(JCMethodDecl tree) {
+            if (tree.body == null) return;
+
+            Bits initsPrev = inits.dup();
+            Bits uninitsPrev = uninits.dup();
+            int nextadrPrev = nextadr;
+            int firstadrPrev = firstadr;
+            Lint lintPrev = lint;
+
+            lint = lint.augment(tree.sym.attributes_field);
+
+            Assert.check(pendingExits.isEmpty());
+
+            try {
+                boolean isInitialConstructor =
+                    TreeInfo.isInitialConstructor(tree);
+
+                if (!isInitialConstructor)
+                    firstadr = nextadr;
+                for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
+                    JCVariableDecl def = l.head;
+                    scan(def);
+                    inits.incl(def.sym.adr);
+                    uninits.excl(def.sym.adr);
                 }
-            }
+                // else we are in an instance initializer block;
+                // leave caught unchanged.
+                scan(tree.body);
 
-            thrown = thrownPrev;
-        } finally {
-            pendingExits = pendingExitsPrev;
-            alive = alivePrev;
-            nextadr = nextadrPrev;
-            firstadr = firstadrPrev;
-            caught = caughtPrev;
-            classDef = classDefPrev;
-            lint = lintPrev;
-        }
-    }
-
-    public void visitMethodDef(JCMethodDecl tree) {
-        if (tree.body == null) return;
-
-        List<Type> caughtPrev = caught;
-        List<Type> mthrown = tree.sym.type.getThrownTypes();
-        Bits initsPrev = inits.dup();
-        Bits uninitsPrev = uninits.dup();
-        int nextadrPrev = nextadr;
-        int firstadrPrev = firstadr;
-        Lint lintPrev = lint;
-
-        lint = lint.augment(tree.sym.attributes_field);
-
-        Assert.check(pendingExits.isEmpty());
-
-        try {
-            boolean isInitialConstructor =
-                TreeInfo.isInitialConstructor(tree);
-
-            if (!isInitialConstructor)
-                firstadr = nextadr;
-            for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
-                JCVariableDecl def = l.head;
-                scan(def);
-                inits.incl(def.sym.adr);
-                uninits.excl(def.sym.adr);
-            }
-            if (isInitialConstructor)
-                caught = chk.union(caught, mthrown);
-            else if ((tree.sym.flags() & (BLOCK | STATIC)) != BLOCK)
-                caught = mthrown;
-            // else we are in an instance initializer block;
-            // leave caught unchanged.
-
-            alive = true;
-            scanStat(tree.body);
-
-            if (alive && tree.sym.type.getReturnType().tag != VOID)
-                log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
-
-            if (isInitialConstructor) {
-                for (int i = firstadr; i < nextadr; i++)
-                    if (vars[i].owner == classDef.sym)
-                        checkInit(TreeInfo.diagEndPos(tree.body), vars[i]);
-            }
-            List<PendingExit> exits = pendingExits.toList();
-            pendingExits = new ListBuffer<PendingExit>();
-            while (exits.nonEmpty()) {
-                PendingExit exit = exits.head;
-                exits = exits.tail;
-                if (exit.thrown == null) {
-                    Assert.check(exit.tree.hasTag(RETURN));
+                if (isInitialConstructor) {
+                    for (int i = firstadr; i < nextadr; i++)
+                        if (vars[i].owner == classDef.sym)
+                            checkInit(TreeInfo.diagEndPos(tree.body), vars[i]);
+                }
+                List<AssignPendingExit> exits = pendingExits.toList();
+                pendingExits = new ListBuffer<AssignPendingExit>();
+                while (exits.nonEmpty()) {
+                    AssignPendingExit exit = exits.head;
+                    exits = exits.tail;
+                    Assert.check(exit.tree.hasTag(RETURN), exit.tree);
                     if (isInitialConstructor) {
-                        inits = exit.inits;
+                        inits = exit.exit_inits;
                         for (int i = firstadr; i < nextadr; i++)
                             checkInit(exit.tree.pos(), vars[i]);
                     }
-                } else {
-                    // uncaught throws will be reported later
-                    pendingExits.append(exit);
                 }
-            }
-        } finally {
-            inits = initsPrev;
-            uninits = uninitsPrev;
-            nextadr = nextadrPrev;
-            firstadr = firstadrPrev;
-            caught = caughtPrev;
-            lint = lintPrev;
-        }
-    }
-
-    public void visitVarDef(JCVariableDecl tree) {
-        boolean track = trackable(tree.sym);
-        if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
-        if (tree.init != null) {
-            Lint lintPrev = lint;
-            lint = lint.augment(tree.sym.attributes_field);
-            try{
-                scanExpr(tree.init);
-                if (track) letInit(tree.pos(), tree.sym);
             } finally {
+                inits = initsPrev;
+                uninits = uninitsPrev;
+                nextadr = nextadrPrev;
+                firstadr = firstadrPrev;
                 lint = lintPrev;
             }
         }
-    }
 
-    public void visitBlock(JCBlock tree) {
-        int nextadrPrev = nextadr;
-        scanStats(tree.stats);
-        nextadr = nextadrPrev;
-    }
+        public void visitVarDef(JCVariableDecl tree) {
+            boolean track = trackable(tree.sym);
+            if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
+            if (tree.init != null) {
+                Lint lintPrev = lint;
+                lint = lint.augment(tree.sym.attributes_field);
+                try{
+                    scanExpr(tree.init);
+                    if (track) letInit(tree.pos(), tree.sym);
+                } finally {
+                    lint = lintPrev;
+                }
+            }
+        }
 
-    public void visitDoLoop(JCDoWhileLoop tree) {
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        boolean prevLoopPassTwo = loopPassTwo;
-        pendingExits = new ListBuffer<PendingExit>();
-        int prevErrors = log.nerrors;
-        do {
-            Bits uninitsEntry = uninits.dup();
-            uninitsEntry.excludeFrom(nextadr);
-            scanStat(tree.body);
-            alive |= resolveContinues(tree);
-            scanCond(tree.cond);
-            if (log.nerrors !=  prevErrors ||
-                loopPassTwo ||
-                uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
-                break;
-            inits = initsWhenTrue;
-            uninits = uninitsEntry.andSet(uninitsWhenTrue);
-            loopPassTwo = true;
-            alive = true;
-        } while (true);
-        loopPassTwo = prevLoopPassTwo;
-        inits = initsWhenFalse;
-        uninits = uninitsWhenFalse;
-        alive = alive && !tree.cond.type.isTrue();
-        alive |= resolveBreaks(tree, prevPendingExits);
-    }
+        public void visitBlock(JCBlock tree) {
+            int nextadrPrev = nextadr;
+            scan(tree.stats);
+            nextadr = nextadrPrev;
+        }
 
-    public void visitWhileLoop(JCWhileLoop tree) {
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        boolean prevLoopPassTwo = loopPassTwo;
-        Bits initsCond;
-        Bits uninitsCond;
-        pendingExits = new ListBuffer<PendingExit>();
-        int prevErrors = log.nerrors;
-        do {
-            Bits uninitsEntry = uninits.dup();
-            uninitsEntry.excludeFrom(nextadr);
-            scanCond(tree.cond);
-            initsCond = initsWhenFalse;
-            uninitsCond = uninitsWhenFalse;
-            inits = initsWhenTrue;
-            uninits = uninitsWhenTrue;
-            alive = !tree.cond.type.isFalse();
-            scanStat(tree.body);
-            alive |= resolveContinues(tree);
-            if (log.nerrors != prevErrors ||
-                loopPassTwo ||
-                uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
-                break;
-            uninits = uninitsEntry.andSet(uninits);
-            loopPassTwo = true;
-            alive = true;
-        } while (true);
-        loopPassTwo = prevLoopPassTwo;
-        inits = initsCond;
-        uninits = uninitsCond;
-        alive = resolveBreaks(tree, prevPendingExits) ||
-            !tree.cond.type.isTrue();
-    }
+        public void visitDoLoop(JCDoWhileLoop tree) {
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            boolean prevLoopPassTwo = loopPassTwo;
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            int prevErrors = log.nerrors;
+            do {
+                Bits uninitsEntry = uninits.dup();
+                uninitsEntry.excludeFrom(nextadr);
+            scan(tree.body);
+            resolveContinues(tree);
+                scanCond(tree.cond);
+                if (log.nerrors !=  prevErrors ||
+                    loopPassTwo ||
+                    uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
+                    break;
+                inits = initsWhenTrue;
+                uninits = uninitsEntry.andSet(uninitsWhenTrue);
+                loopPassTwo = true;
+            } while (true);
+            loopPassTwo = prevLoopPassTwo;
+            inits = initsWhenFalse;
+            uninits = uninitsWhenFalse;
+            resolveBreaks(tree, prevPendingExits);
+        }
 
-    public void visitForLoop(JCForLoop tree) {
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        boolean prevLoopPassTwo = loopPassTwo;
-        int nextadrPrev = nextadr;
-        scanStats(tree.init);
-        Bits initsCond;
-        Bits uninitsCond;
-        pendingExits = new ListBuffer<PendingExit>();
-        int prevErrors = log.nerrors;
-        do {
-            Bits uninitsEntry = uninits.dup();
-            uninitsEntry.excludeFrom(nextadr);
-            if (tree.cond != null) {
+        public void visitWhileLoop(JCWhileLoop tree) {
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            boolean prevLoopPassTwo = loopPassTwo;
+            Bits initsCond;
+            Bits uninitsCond;
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            int prevErrors = log.nerrors;
+            do {
+                Bits uninitsEntry = uninits.dup();
+                uninitsEntry.excludeFrom(nextadr);
                 scanCond(tree.cond);
                 initsCond = initsWhenFalse;
                 uninitsCond = uninitsWhenFalse;
                 inits = initsWhenTrue;
                 uninits = uninitsWhenTrue;
-                alive = !tree.cond.type.isFalse();
+                scan(tree.body);
+                resolveContinues(tree);
+                if (log.nerrors != prevErrors ||
+                    loopPassTwo ||
+                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
+                    break;
+                uninits = uninitsEntry.andSet(uninits);
+                loopPassTwo = true;
+            } while (true);
+            loopPassTwo = prevLoopPassTwo;
+            inits = initsCond;
+            uninits = uninitsCond;
+            resolveBreaks(tree, prevPendingExits);
+        }
+
+        public void visitForLoop(JCForLoop tree) {
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            boolean prevLoopPassTwo = loopPassTwo;
+            int nextadrPrev = nextadr;
+            scan(tree.init);
+            Bits initsCond;
+            Bits uninitsCond;
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            int prevErrors = log.nerrors;
+            do {
+                Bits uninitsEntry = uninits.dup();
+                uninitsEntry.excludeFrom(nextadr);
+                if (tree.cond != null) {
+                    scanCond(tree.cond);
+                    initsCond = initsWhenFalse;
+                    uninitsCond = uninitsWhenFalse;
+                    inits = initsWhenTrue;
+                    uninits = uninitsWhenTrue;
+                } else {
+                    initsCond = inits.dup();
+                    initsCond.inclRange(firstadr, nextadr);
+                    uninitsCond = uninits.dup();
+                    uninitsCond.inclRange(firstadr, nextadr);
+                }
+                scan(tree.body);
+                resolveContinues(tree);
+                scan(tree.step);
+                if (log.nerrors != prevErrors ||
+                    loopPassTwo ||
+                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
+                    break;
+                uninits = uninitsEntry.andSet(uninits);
+                loopPassTwo = true;
+            } while (true);
+            loopPassTwo = prevLoopPassTwo;
+            inits = initsCond;
+            uninits = uninitsCond;
+            resolveBreaks(tree, prevPendingExits);
+            nextadr = nextadrPrev;
+        }
+
+        public void visitForeachLoop(JCEnhancedForLoop tree) {
+            visitVarDef(tree.var);
+
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            boolean prevLoopPassTwo = loopPassTwo;
+            int nextadrPrev = nextadr;
+            scan(tree.expr);
+            Bits initsStart = inits.dup();
+            Bits uninitsStart = uninits.dup();
+
+            letInit(tree.pos(), tree.var.sym);
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            int prevErrors = log.nerrors;
+            do {
+                Bits uninitsEntry = uninits.dup();
+                uninitsEntry.excludeFrom(nextadr);
+                scan(tree.body);
+                resolveContinues(tree);
+                if (log.nerrors != prevErrors ||
+                    loopPassTwo ||
+                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
+                    break;
+                uninits = uninitsEntry.andSet(uninits);
+                loopPassTwo = true;
+            } while (true);
+            loopPassTwo = prevLoopPassTwo;
+            inits = initsStart;
+            uninits = uninitsStart.andSet(uninits);
+            resolveBreaks(tree, prevPendingExits);
+            nextadr = nextadrPrev;
+        }
+
+        public void visitLabelled(JCLabeledStatement tree) {
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            scan(tree.body);
+            resolveBreaks(tree, prevPendingExits);
+        }
+
+        public void visitSwitch(JCSwitch tree) {
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            int nextadrPrev = nextadr;
+            scanExpr(tree.selector);
+            Bits initsSwitch = inits;
+            Bits uninitsSwitch = uninits.dup();
+            boolean hasDefault = false;
+            for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
+                inits = initsSwitch.dup();
+                uninits = uninits.andSet(uninitsSwitch);
+                JCCase c = l.head;
+                if (c.pat == null)
+                    hasDefault = true;
+                else
+                    scanExpr(c.pat);
+                scan(c.stats);
+                addVars(c.stats, initsSwitch, uninitsSwitch);
+                // Warn about fall-through if lint switch fallthrough enabled.
+            }
+            if (!hasDefault) {
+                inits.andSet(initsSwitch);
+            }
+            resolveBreaks(tree, prevPendingExits);
+            nextadr = nextadrPrev;
+        }
+        // where
+            /** Add any variables defined in stats to inits and uninits. */
+            private void addVars(List<JCStatement> stats, Bits inits,
+                                        Bits uninits) {
+                for (;stats.nonEmpty(); stats = stats.tail) {
+                    JCTree stat = stats.head;
+                    if (stat.hasTag(VARDEF)) {
+                        int adr = ((JCVariableDecl) stat).sym.adr;
+                        inits.excl(adr);
+                        uninits.incl(adr);
+                    }
+                }
+            }
+
+        public void visitTry(JCTry tree) {
+            ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
+            Bits uninitsTryPrev = uninitsTry;
+            ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+            pendingExits = new ListBuffer<AssignPendingExit>();
+            Bits initsTry = inits.dup();
+            uninitsTry = uninits.dup();
+            for (JCTree resource : tree.resources) {
+                if (resource instanceof JCVariableDecl) {
+                    JCVariableDecl vdecl = (JCVariableDecl) resource;
+                    visitVarDef(vdecl);
+                    unrefdResources.enter(vdecl.sym);
+                    resourceVarDecls.append(vdecl);
+                } else if (resource instanceof JCExpression) {
+                    scanExpr((JCExpression) resource);
+                } else {
+                    throw new AssertionError(tree);  // parser error
+                }
+            }
+            scan(tree.body);
+            uninitsTry.andSet(uninits);
+            Bits initsEnd = inits;
+            Bits uninitsEnd = uninits;
+            int nextadrCatch = nextadr;
+
+            if (!resourceVarDecls.isEmpty() &&
+                    lint.isEnabled(Lint.LintCategory.TRY)) {
+                for (JCVariableDecl resVar : resourceVarDecls) {
+                    if (unrefdResources.includes(resVar.sym)) {
+                        log.warning(Lint.LintCategory.TRY, resVar.pos(),
+                                    "try.resource.not.referenced", resVar.sym);
+                        unrefdResources.remove(resVar.sym);
+                    }
+                }
+            }
+
+            for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
+                JCVariableDecl param = l.head.param;
+                inits = initsTry.dup();
+                uninits = uninitsTry.dup();
+                scan(param);
+                inits.incl(param.sym.adr);
+                uninits.excl(param.sym.adr);
+                scan(l.head.body);
+                initsEnd.andSet(inits);
+                uninitsEnd.andSet(uninits);
+                nextadr = nextadrCatch;
+            }
+            if (tree.finalizer != null) {
+                inits = initsTry.dup();
+                uninits = uninitsTry.dup();
+                ListBuffer<AssignPendingExit> exits = pendingExits;
+                pendingExits = prevPendingExits;
+                scan(tree.finalizer);
+                if (!tree.finallyCanCompleteNormally) {
+                    // discard exits and exceptions from try and finally
+                } else {
+                    uninits.andSet(uninitsEnd);
+                    // FIX: this doesn't preserve source order of exits in catch
+                    // versus finally!
+                    while (exits.nonEmpty()) {
+                        AssignPendingExit exit = exits.next();
+                        if (exit.exit_inits != null) {
+                            exit.exit_inits.orSet(inits);
+                            exit.exit_uninits.andSet(uninits);
+                        }
+                        pendingExits.append(exit);
+                    }
+                    inits.orSet(initsEnd);
+                }
             } else {
-                initsCond = inits.dup();
-                initsCond.inclRange(firstadr, nextadr);
-                uninitsCond = uninits.dup();
-                uninitsCond.inclRange(firstadr, nextadr);
-                alive = true;
+                inits = initsEnd;
+                uninits = uninitsEnd;
+                ListBuffer<AssignPendingExit> exits = pendingExits;
+                pendingExits = prevPendingExits;
+                while (exits.nonEmpty()) pendingExits.append(exits.next());
             }
-            scanStat(tree.body);
-            alive |= resolveContinues(tree);
-            scan(tree.step);
-            if (log.nerrors != prevErrors ||
-                loopPassTwo ||
-                uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
-                break;
-            uninits = uninitsEntry.andSet(uninits);
-            loopPassTwo = true;
-            alive = true;
-        } while (true);
-        loopPassTwo = prevLoopPassTwo;
-        inits = initsCond;
-        uninits = uninitsCond;
-        alive = resolveBreaks(tree, prevPendingExits) ||
-            tree.cond != null && !tree.cond.type.isTrue();
-        nextadr = nextadrPrev;
-    }
+            uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
+        }
 
-    public void visitForeachLoop(JCEnhancedForLoop tree) {
-        visitVarDef(tree.var);
-
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        boolean prevLoopPassTwo = loopPassTwo;
-        int nextadrPrev = nextadr;
-        scan(tree.expr);
-        Bits initsStart = inits.dup();
-        Bits uninitsStart = uninits.dup();
-
-        letInit(tree.pos(), tree.var.sym);
-        pendingExits = new ListBuffer<PendingExit>();
-        int prevErrors = log.nerrors;
-        do {
-            Bits uninitsEntry = uninits.dup();
-            uninitsEntry.excludeFrom(nextadr);
-            scanStat(tree.body);
-            alive |= resolveContinues(tree);
-            if (log.nerrors != prevErrors ||
-                loopPassTwo ||
-                uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
-                break;
-            uninits = uninitsEntry.andSet(uninits);
-            loopPassTwo = true;
-            alive = true;
-        } while (true);
-        loopPassTwo = prevLoopPassTwo;
-        inits = initsStart;
-        uninits = uninitsStart.andSet(uninits);
-        resolveBreaks(tree, prevPendingExits);
-        alive = true;
-        nextadr = nextadrPrev;
-    }
-
-    public void visitLabelled(JCLabeledStatement tree) {
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        pendingExits = new ListBuffer<PendingExit>();
-        scanStat(tree.body);
-        alive |= resolveBreaks(tree, prevPendingExits);
-    }
-
-    public void visitSwitch(JCSwitch tree) {
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        pendingExits = new ListBuffer<PendingExit>();
-        int nextadrPrev = nextadr;
-        scanExpr(tree.selector);
-        Bits initsSwitch = inits;
-        Bits uninitsSwitch = uninits.dup();
-        boolean hasDefault = false;
-        for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
-            alive = true;
-            inits = initsSwitch.dup();
-            uninits = uninits.andSet(uninitsSwitch);
-            JCCase c = l.head;
-            if (c.pat == null)
-                hasDefault = true;
-            else
-                scanExpr(c.pat);
-            scanStats(c.stats);
-            addVars(c.stats, initsSwitch, uninitsSwitch);
-            // Warn about fall-through if lint switch fallthrough enabled.
-            if (!loopPassTwo &&
-                alive &&
-                lint.isEnabled(Lint.LintCategory.FALLTHROUGH) &&
-                c.stats.nonEmpty() && l.tail.nonEmpty())
-                log.warning(Lint.LintCategory.FALLTHROUGH,
-                            l.tail.head.pos(),
-                            "possible.fall-through.into.case");
-        }
-        if (!hasDefault) {
-            inits.andSet(initsSwitch);
-            alive = true;
-        }
-        alive |= resolveBreaks(tree, prevPendingExits);
-        nextadr = nextadrPrev;
-    }
-    // where
-        /** Add any variables defined in stats to inits and uninits. */
-        private static void addVars(List<JCStatement> stats, Bits inits,
-                                    Bits uninits) {
-            for (;stats.nonEmpty(); stats = stats.tail) {
-                JCTree stat = stats.head;
-                if (stat.hasTag(VARDEF)) {
-                    int adr = ((JCVariableDecl) stat).sym.adr;
-                    inits.excl(adr);
-                    uninits.incl(adr);
-                }
+        public void visitConditional(JCConditional tree) {
+            scanCond(tree.cond);
+            Bits initsBeforeElse = initsWhenFalse;
+            Bits uninitsBeforeElse = uninitsWhenFalse;
+            inits = initsWhenTrue;
+            uninits = uninitsWhenTrue;
+            if (tree.truepart.type.tag == BOOLEAN &&
+                tree.falsepart.type.tag == BOOLEAN) {
+                // if b and c are boolean valued, then
+                // v is (un)assigned after a?b:c when true iff
+                //    v is (un)assigned after b when true and
+                //    v is (un)assigned after c when true
+                scanCond(tree.truepart);
+                Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
+                Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
+                Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
+                Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
+                inits = initsBeforeElse;
+                uninits = uninitsBeforeElse;
+                scanCond(tree.falsepart);
+                initsWhenTrue.andSet(initsAfterThenWhenTrue);
+                initsWhenFalse.andSet(initsAfterThenWhenFalse);
+                uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue);
+                uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
+            } else {
+                scanExpr(tree.truepart);
+                Bits initsAfterThen = inits.dup();
+                Bits uninitsAfterThen = uninits.dup();
+                inits = initsBeforeElse;
+                uninits = uninitsBeforeElse;
+                scanExpr(tree.falsepart);
+                inits.andSet(initsAfterThen);
+                uninits.andSet(uninitsAfterThen);
             }
         }
 
-    public void visitTry(JCTry tree) {
-        List<Type> caughtPrev = caught;
-        List<Type> thrownPrev = thrown;
-        thrown = List.nil();
-        for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
-            List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
-                    ((JCTypeUnion)l.head.param.vartype).alternatives :
-                    List.of(l.head.param.vartype);
-            for (JCExpression ct : subClauses) {
-                caught = chk.incl(ct.type, caught);
-            }
-        }
-        ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
-        Bits uninitsTryPrev = uninitsTry;
-        ListBuffer<PendingExit> prevPendingExits = pendingExits;
-        pendingExits = new ListBuffer<PendingExit>();
-        Bits initsTry = inits.dup();
-        uninitsTry = uninits.dup();
-        for (JCTree resource : tree.resources) {
-            if (resource instanceof JCVariableDecl) {
-                JCVariableDecl vdecl = (JCVariableDecl) resource;
-                visitVarDef(vdecl);
-                unrefdResources.enter(vdecl.sym);
-                resourceVarDecls.append(vdecl);
-            } else if (resource instanceof JCExpression) {
-                scanExpr((JCExpression) resource);
+        public void visitIf(JCIf tree) {
+            scanCond(tree.cond);
+            Bits initsBeforeElse = initsWhenFalse;
+            Bits uninitsBeforeElse = uninitsWhenFalse;
+            inits = initsWhenTrue;
+            uninits = uninitsWhenTrue;
+            scan(tree.thenpart);
+            if (tree.elsepart != null) {
+                Bits initsAfterThen = inits.dup();
+                Bits uninitsAfterThen = uninits.dup();
+                inits = initsBeforeElse;
+                uninits = uninitsBeforeElse;
+                scan(tree.elsepart);
+                inits.andSet(initsAfterThen);
+                uninits.andSet(uninitsAfterThen);
             } else {
-                throw new AssertionError(tree);  // parser error
-            }
-        }
-        for (JCTree resource : tree.resources) {
-            List<Type> closeableSupertypes = resource.type.isCompound() ?
-                types.interfaces(resource.type).prepend(types.supertype(resource.type)) :
-                List.of(resource.type);
-            for (Type sup : closeableSupertypes) {
-                if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) {
-                    Symbol closeMethod = rs.resolveQualifiedMethod(tree,
-                            attrEnv,
-                            sup,
-                            names.close,
-                            List.<Type>nil(),
-                            List.<Type>nil());
-                    if (closeMethod.kind == MTH) {
-                        for (Type t : ((MethodSymbol)closeMethod).getThrownTypes()) {
-                            markThrown(resource, t);
-                        }
-                    }
-                }
-            }
-        }
-        scanStat(tree.body);
-        List<Type> thrownInTry = allowImprovedCatchAnalysis ?
-            chk.union(thrown, List.of(syms.runtimeExceptionType, syms.errorType)) :
-            thrown;
-        thrown = thrownPrev;
-        caught = caughtPrev;
-        boolean aliveEnd = alive;
-        uninitsTry.andSet(uninits);
-        Bits initsEnd = inits;
-        Bits uninitsEnd = uninits;
-        int nextadrCatch = nextadr;
-
-        if (!resourceVarDecls.isEmpty() &&
-                lint.isEnabled(Lint.LintCategory.TRY)) {
-            for (JCVariableDecl resVar : resourceVarDecls) {
-                if (unrefdResources.includes(resVar.sym)) {
-                    log.warning(Lint.LintCategory.TRY, resVar.pos(),
-                                "try.resource.not.referenced", resVar.sym);
-                    unrefdResources.remove(resVar.sym);
-                }
+                inits.andSet(initsBeforeElse);
+                uninits.andSet(uninitsBeforeElse);
             }
         }
 
-        List<Type> caughtInTry = List.nil();
-        for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
-            alive = true;
-            JCVariableDecl param = l.head.param;
-            List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
-                    ((JCTypeUnion)l.head.param.vartype).alternatives :
-                    List.of(l.head.param.vartype);
-            List<Type> ctypes = List.nil();
-            List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
-            for (JCExpression ct : subClauses) {
-                Type exc = ct.type;
-                if (exc != syms.unknownType) {
-                    ctypes = ctypes.append(exc);
-                    if (types.isSameType(exc, syms.objectType))
-                        continue;
-                    checkCaughtType(l.head.pos(), exc, thrownInTry, caughtInTry);
-                    caughtInTry = chk.incl(exc, caughtInTry);
-                }
+        public void visitBreak(JCBreak tree) {
+            recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+        }
+
+        public void visitContinue(JCContinue tree) {
+            recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+        }
+
+        public void visitReturn(JCReturn tree) {
+            scanExpr(tree.expr);
+            // if not initial constructor, should markDead instead of recordExit
+            recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+        }
+
+        public void visitThrow(JCThrow tree) {
+            scanExpr(tree.expr);
+            markDead();
+        }
+
+        public void visitApply(JCMethodInvocation tree) {
+            scanExpr(tree.meth);
+            scanExprs(tree.args);
+        }
+
+        public void visitNewClass(JCNewClass tree) {
+            scanExpr(tree.encl);
+            scanExprs(tree.args);
+            scan(tree.def);
+        }
+
+        public void visitNewArray(JCNewArray tree) {
+            scanExprs(tree.dims);
+            scanExprs(tree.elems);
+        }
+
+        public void visitAssert(JCAssert tree) {
+            Bits initsExit = inits.dup();
+            Bits uninitsExit = uninits.dup();
+            scanCond(tree.cond);
+            uninitsExit.andSet(uninitsWhenTrue);
+            if (tree.detail != null) {
+                inits = initsWhenFalse;
+                uninits = uninitsWhenFalse;
+                scanExpr(tree.detail);
             }
-            inits = initsTry.dup();
-            uninits = uninitsTry.dup();
-            scan(param);
-            inits.incl(param.sym.adr);
-            uninits.excl(param.sym.adr);
-            preciseRethrowTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
-            scanStat(l.head.body);
-            initsEnd.andSet(inits);
-            uninitsEnd.andSet(uninits);
-            nextadr = nextadrCatch;
-            preciseRethrowTypes.remove(param.sym);
-            aliveEnd |= alive;
+            inits = initsExit;
+            uninits = uninitsExit;
         }
-        if (tree.finalizer != null) {
-            List<Type> savedThrown = thrown;
-            thrown = List.nil();
-            inits = initsTry.dup();
-            uninits = uninitsTry.dup();
-            ListBuffer<PendingExit> exits = pendingExits;
-            pendingExits = prevPendingExits;
-            alive = true;
-            scanStat(tree.finalizer);
-            if (!alive) {
-                // discard exits and exceptions from try and finally
-                thrown = chk.union(thrown, thrownPrev);
-                if (!loopPassTwo &&
-                    lint.isEnabled(Lint.LintCategory.FINALLY)) {
-                    log.warning(Lint.LintCategory.FINALLY,
-                            TreeInfo.diagEndPos(tree.finalizer),
-                            "finally.cannot.complete");
-                }
-            } else {
-                thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
-                thrown = chk.union(thrown, savedThrown);
-                uninits.andSet(uninitsEnd);
-                // FIX: this doesn't preserve source order of exits in catch
-                // versus finally!
-                while (exits.nonEmpty()) {
-                    PendingExit exit = exits.next();
-                    if (exit.inits != null) {
-                        exit.inits.orSet(inits);
-                        exit.uninits.andSet(uninits);
-                    }
-                    pendingExits.append(exit);
-                }
-                inits.orSet(initsEnd);
-                alive = aliveEnd;
+
+        public void visitAssign(JCAssign tree) {
+            JCTree lhs = TreeInfo.skipParens(tree.lhs);
+            if (!(lhs instanceof JCIdent)) scanExpr(lhs);
+            scanExpr(tree.rhs);
+            letInit(lhs);
+        }
+
+        public void visitAssignop(JCAssignOp tree) {
+            scanExpr(tree.lhs);
+            scanExpr(tree.rhs);
+            letInit(tree.lhs);
+        }
+
+        public void visitUnary(JCUnary tree) {
+            switch (tree.getTag()) {
+            case NOT:
+                scanCond(tree.arg);
+                Bits t = initsWhenFalse;
+                initsWhenFalse = initsWhenTrue;
+                initsWhenTrue = t;
+                t = uninitsWhenFalse;
+                uninitsWhenFalse = uninitsWhenTrue;
+                uninitsWhenTrue = t;
+                break;
+            case PREINC: case POSTINC:
+            case PREDEC: case POSTDEC:
+                scanExpr(tree.arg);
+                letInit(tree.arg);
+                break;
+            default:
+                scanExpr(tree.arg);
             }
-        } else {
-            thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
-            inits = initsEnd;
-            uninits = uninitsEnd;
-            alive = aliveEnd;
-            ListBuffer<PendingExit> exits = pendingExits;
-            pendingExits = prevPendingExits;
-            while (exits.nonEmpty()) pendingExits.append(exits.next());
         }
-        uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
-    }
 
-    void checkCaughtType(DiagnosticPosition pos, Type exc, List<Type> thrownInTry, List<Type> caughtInTry) {
-        if (chk.subset(exc, caughtInTry)) {
-            log.error(pos, "except.already.caught", exc);
-        } else if (!chk.isUnchecked(pos, exc) &&
-                !isExceptionOrThrowable(exc) &&
-                !chk.intersects(exc, thrownInTry)) {
-            log.error(pos, "except.never.thrown.in.try", exc);
-        } else if (allowImprovedCatchAnalysis) {
-            List<Type> catchableThrownTypes = chk.intersect(List.of(exc), thrownInTry);
-            // 'catchableThrownTypes' cannnot possibly be empty - if 'exc' was an
-            // unchecked exception, the result list would not be empty, as the augmented
-            // thrown set includes { RuntimeException, Error }; if 'exc' was a checked
-            // exception, that would have been covered in the branch above
-            if (chk.diff(catchableThrownTypes, caughtInTry).isEmpty() &&
-                    !isExceptionOrThrowable(exc)) {
-                String key = catchableThrownTypes.length() == 1 ?
-                        "unreachable.catch" :
-                        "unreachable.catch.1";
-                log.warning(pos, key, catchableThrownTypes);
+        public void visitBinary(JCBinary tree) {
+            switch (tree.getTag()) {
+            case AND:
+                scanCond(tree.lhs);
+                Bits initsWhenFalseLeft = initsWhenFalse;
+                Bits uninitsWhenFalseLeft = uninitsWhenFalse;
+                inits = initsWhenTrue;
+                uninits = uninitsWhenTrue;
+                scanCond(tree.rhs);
+                initsWhenFalse.andSet(initsWhenFalseLeft);
+                uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
+                break;
+            case OR:
+                scanCond(tree.lhs);
+                Bits initsWhenTrueLeft = initsWhenTrue;
+                Bits uninitsWhenTrueLeft = uninitsWhenTrue;
+                inits = initsWhenFalse;
+                uninits = uninitsWhenFalse;
+                scanCond(tree.rhs);
+                initsWhenTrue.andSet(initsWhenTrueLeft);
+                uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
+                break;
+            default:
+                scanExpr(tree.lhs);
+                scanExpr(tree.rhs);
+            }
+        }
+
+        public void visitIdent(JCIdent tree) {
+            if (tree.sym.kind == VAR) {
+                checkInit(tree.pos(), (VarSymbol)tree.sym);
+                referenced(tree.sym);
+            }
+        }
+
+        void referenced(Symbol sym) {
+            unrefdResources.remove(sym);
+        }
+
+        public void visitTopLevel(JCCompilationUnit tree) {
+            // Do nothing for TopLevel since each class is visited individually
+        }
+
+    /**************************************************************************
+     * main method
+     *************************************************************************/
+
+        /** Perform definite assignment/unassignment analysis on a tree.
+         */
+        public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
+            try {
+                attrEnv = env;
+                JCTree tree = env.tree;
+                Flow.this.make = make;
+                inits = new Bits();
+                uninits = new Bits();
+                uninitsTry = new Bits();
+                initsWhenTrue = initsWhenFalse =
+                    uninitsWhenTrue = uninitsWhenFalse = null;
+                if (vars == null)
+                    vars = new VarSymbol[32];
+                else
+                    for (int i=0; i<vars.length; i++)
+                        vars[i] = null;
+                firstadr = 0;
+                nextadr = 0;
+                pendingExits = new ListBuffer<AssignPendingExit>();
+                this.classDef = null;
+                unrefdResources = new Scope(env.enclClass.sym);
+                scan(tree);
+            } finally {
+                // note that recursive invocations of this method fail hard
+                inits = uninits = uninitsTry = null;
+                initsWhenTrue = initsWhenFalse =
+                    uninitsWhenTrue = uninitsWhenFalse = null;
+                if (vars != null) for (int i=0; i<vars.length; i++)
+                    vars[i] = null;
+                firstadr = 0;
+                nextadr = 0;
+                pendingExits = null;
+                Flow.this.make = null;
+                this.classDef = null;
+                unrefdResources = null;
             }
         }
     }
-    //where
-        private boolean isExceptionOrThrowable(Type exc) {
-            return exc.tsym == syms.throwableType.tsym ||
-                exc.tsym == syms.exceptionType.tsym;
-        }
-
-
-    public void visitConditional(JCConditional tree) {
-        scanCond(tree.cond);
-        Bits initsBeforeElse = initsWhenFalse;
-        Bits uninitsBeforeElse = uninitsWhenFalse;
-        inits = initsWhenTrue;
-        uninits = uninitsWhenTrue;
-        if (tree.truepart.type.tag == BOOLEAN &&
-            tree.falsepart.type.tag == BOOLEAN) {
-            // if b and c are boolean valued, then
-            // v is (un)assigned after a?b:c when true iff
-            //    v is (un)assigned after b when true and
-            //    v is (un)assigned after c when true
-            scanCond(tree.truepart);
-            Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
-            Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
-            Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
-            Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
-            inits = initsBeforeElse;
-            uninits = uninitsBeforeElse;
-            scanCond(tree.falsepart);
-            initsWhenTrue.andSet(initsAfterThenWhenTrue);
-            initsWhenFalse.andSet(initsAfterThenWhenFalse);
-            uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue);
-            uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
-        } else {
-            scanExpr(tree.truepart);
-            Bits initsAfterThen = inits.dup();
-            Bits uninitsAfterThen = uninits.dup();
-            inits = initsBeforeElse;
-            uninits = uninitsBeforeElse;
-            scanExpr(tree.falsepart);
-            inits.andSet(initsAfterThen);
-            uninits.andSet(uninitsAfterThen);
-        }
-    }
-
-    public void visitIf(JCIf tree) {
-        scanCond(tree.cond);
-        Bits initsBeforeElse = initsWhenFalse;
-        Bits uninitsBeforeElse = uninitsWhenFalse;
-        inits = initsWhenTrue;
-        uninits = uninitsWhenTrue;
-        scanStat(tree.thenpart);
-        if (tree.elsepart != null) {
-            boolean aliveAfterThen = alive;
-            alive = true;
-            Bits initsAfterThen = inits.dup();
-            Bits uninitsAfterThen = uninits.dup();
-            inits = initsBeforeElse;
-            uninits = uninitsBeforeElse;
-            scanStat(tree.elsepart);
-            inits.andSet(initsAfterThen);
-            uninits.andSet(uninitsAfterThen);
-            alive = alive | aliveAfterThen;
-        } else {
-            inits.andSet(initsBeforeElse);
-            uninits.andSet(uninitsBeforeElse);
-            alive = true;
-        }
-    }
-
-
-
-    public void visitBreak(JCBreak tree) {
-        recordExit(tree);
-    }
-
-    public void visitContinue(JCContinue tree) {
-        recordExit(tree);
-    }
-
-    public void visitReturn(JCReturn tree) {
-        scanExpr(tree.expr);
-        // if not initial constructor, should markDead instead of recordExit
-        recordExit(tree);
-    }
-
-    public void visitThrow(JCThrow tree) {
-        scanExpr(tree.expr);
-        Symbol sym = TreeInfo.symbol(tree.expr);
-        if (sym != null &&
-            sym.kind == VAR &&
-            (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 &&
-            preciseRethrowTypes.get(sym) != null &&
-            allowImprovedRethrowAnalysis) {
-            for (Type t : preciseRethrowTypes.get(sym)) {
-                markThrown(tree, t);
-            }
-        }
-        else {
-            markThrown(tree, tree.expr.type);
-        }
-        markDead();
-    }
-
-    public void visitApply(JCMethodInvocation tree) {
-        scanExpr(tree.meth);
-        scanExprs(tree.args);
-        for (List<Type> l = tree.meth.type.getThrownTypes(); l.nonEmpty(); l = l.tail)
-            markThrown(tree, l.head);
-    }
-
-    public void visitNewClass(JCNewClass tree) {
-        scanExpr(tree.encl);
-        scanExprs(tree.args);
-       // scan(tree.def);
-        for (List<Type> l = tree.constructorType.getThrownTypes();
-             l.nonEmpty();
-             l = l.tail) {
-            markThrown(tree, l.head);
-        }
-        List<Type> caughtPrev = caught;
-        try {
-            // If the new class expression defines an anonymous class,
-            // analysis of the anonymous constructor may encounter thrown
-            // types which are unsubstituted type variables.
-            // However, since the constructor's actual thrown types have
-            // already been marked as thrown, it is safe to simply include
-            // each of the constructor's formal thrown types in the set of
-            // 'caught/declared to be thrown' types, for the duration of
-            // the class def analysis.
-            if (tree.def != null)
-                for (List<Type> l = tree.constructor.type.getThrownTypes();
-                     l.nonEmpty();
-                     l = l.tail) {
-                    caught = chk.incl(l.head, caught);
-                }
-            scan(tree.def);
-        }
-        finally {
-            caught = caughtPrev;
-        }
-    }
-
-    public void visitNewArray(JCNewArray tree) {
-        scanExprs(tree.dims);
-        scanExprs(tree.elems);
-    }
-
-    public void visitAssert(JCAssert tree) {
-        Bits initsExit = inits.dup();
-        Bits uninitsExit = uninits.dup();
-        scanCond(tree.cond);
-        uninitsExit.andSet(uninitsWhenTrue);
-        if (tree.detail != null) {
-            inits = initsWhenFalse;
-            uninits = uninitsWhenFalse;
-            scanExpr(tree.detail);
-        }
-        inits = initsExit;
-        uninits = uninitsExit;
-    }
-
-    public void visitAssign(JCAssign tree) {
-        JCTree lhs = TreeInfo.skipParens(tree.lhs);
-        if (!(lhs instanceof JCIdent)) scanExpr(lhs);
-        scanExpr(tree.rhs);
-        letInit(lhs);
-    }
-
-    public void visitAssignop(JCAssignOp tree) {
-        scanExpr(tree.lhs);
-        scanExpr(tree.rhs);
-        letInit(tree.lhs);
-    }
-
-    public void visitUnary(JCUnary tree) {
-        switch (tree.getTag()) {
-        case NOT:
-            scanCond(tree.arg);
-            Bits t = initsWhenFalse;
-            initsWhenFalse = initsWhenTrue;
-            initsWhenTrue = t;
-            t = uninitsWhenFalse;
-            uninitsWhenFalse = uninitsWhenTrue;
-            uninitsWhenTrue = t;
-            break;
-        case PREINC: case POSTINC:
-        case PREDEC: case POSTDEC:
-            scanExpr(tree.arg);
-            letInit(tree.arg);
-            break;
-        default:
-            scanExpr(tree.arg);
-        }
-    }
-
-    public void visitBinary(JCBinary tree) {
-        switch (tree.getTag()) {
-        case AND:
-            scanCond(tree.lhs);
-            Bits initsWhenFalseLeft = initsWhenFalse;
-            Bits uninitsWhenFalseLeft = uninitsWhenFalse;
-            inits = initsWhenTrue;
-            uninits = uninitsWhenTrue;
-            scanCond(tree.rhs);
-            initsWhenFalse.andSet(initsWhenFalseLeft);
-            uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
-            break;
-        case OR:
-            scanCond(tree.lhs);
-            Bits initsWhenTrueLeft = initsWhenTrue;
-            Bits uninitsWhenTrueLeft = uninitsWhenTrue;
-            inits = initsWhenFalse;
-            uninits = uninitsWhenFalse;
-            scanCond(tree.rhs);
-            initsWhenTrue.andSet(initsWhenTrueLeft);
-            uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
-            break;
-        default:
-            scanExpr(tree.lhs);
-            scanExpr(tree.rhs);
-        }
-    }
-
-    public void visitIdent(JCIdent tree) {
-        if (tree.sym.kind == VAR) {
-            checkInit(tree.pos(), (VarSymbol)tree.sym);
-            referenced(tree.sym);
-        }
-    }
-
-    void referenced(Symbol sym) {
-        unrefdResources.remove(sym);
-    }
-
-    public void visitTypeCast(JCTypeCast tree) {
-        super.visitTypeCast(tree);
-        if (!tree.type.isErroneous()
-            && lint.isEnabled(Lint.LintCategory.CAST)
-            && types.isSameType(tree.expr.type, tree.clazz.type)
-            && !is292targetTypeCast(tree)) {
-            log.warning(Lint.LintCategory.CAST,
-                    tree.pos(), "redundant.cast", tree.expr.type);
-        }
-    }
-    //where
-        private boolean is292targetTypeCast(JCTypeCast tree) {
-            boolean is292targetTypeCast = false;
-            JCExpression expr = TreeInfo.skipParens(tree.expr);
-            if (expr.hasTag(APPLY)) {
-                JCMethodInvocation apply = (JCMethodInvocation)expr;
-                Symbol sym = TreeInfo.symbol(apply.meth);
-                is292targetTypeCast = sym != null &&
-                    sym.kind == MTH &&
-                    (sym.flags() & POLYMORPHIC_SIGNATURE) != 0;
-            }
-            return is292targetTypeCast;
-        }
-
-    public void visitTopLevel(JCCompilationUnit tree) {
-        // Do nothing for TopLevel since each class is visited individually
-    }
-
-/**************************************************************************
- * main method
- *************************************************************************/
-
-    /** Perform definite assignment/unassignment analysis on a tree.
-     */
-    public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
-        try {
-            attrEnv = env;
-            JCTree tree = env.tree;
-            this.make = make;
-            inits = new Bits();
-            uninits = new Bits();
-            uninitsTry = new Bits();
-            initsWhenTrue = initsWhenFalse =
-                uninitsWhenTrue = uninitsWhenFalse = null;
-            if (vars == null)
-                vars = new VarSymbol[32];
-            else
-                for (int i=0; i<vars.length; i++)
-                    vars[i] = null;
-            firstadr = 0;
-            nextadr = 0;
-            pendingExits = new ListBuffer<PendingExit>();
-            preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
-            alive = true;
-            this.thrown = this.caught = null;
-            this.classDef = null;
-            unrefdResources = new Scope(env.enclClass.sym);
-            scan(tree);
-        } finally {
-            // note that recursive invocations of this method fail hard
-            inits = uninits = uninitsTry = null;
-            initsWhenTrue = initsWhenFalse =
-                uninitsWhenTrue = uninitsWhenFalse = null;
-            if (vars != null) for (int i=0; i<vars.length; i++)
-                vars[i] = null;
-            firstadr = 0;
-            nextadr = 0;
-            pendingExits = null;
-            this.make = null;
-            this.thrown = this.caught = null;
-            this.classDef = null;
-            unrefdResources = null;
-        }
-    }
 }
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Apr 09 21:58:05 2012 -0700
@@ -347,7 +347,7 @@
                     that.tvars,
                     instantiateAsUninferredVars(undetvars, that.tvars));
         }
-        return chk.checkType(warn.pos(), that.inst(targs, types), to);
+        return that.inst(targs, types);
     }
     //where
     private List<Type> instantiateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
@@ -603,8 +603,7 @@
      * method signature. The target return type is computed from the immediately
      * enclosing scope surrounding the polymorphic-signature call.
      */
-    Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env, Type site,
-                                            Name name,
+    Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env,
                                             MethodSymbol spMethod,  // sig. poly. method or null if none
                                             List<Type> argtypes) {
         final Type restype;
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Apr 09 21:58:05 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -781,20 +781,6 @@
                 && s.owner.kind != MTH
                 && types.isSameType(c.type, syms.deprecatedType))
                 s.flags_field |= Flags.DEPRECATED;
-            // Internally to java.lang.invoke, a @PolymorphicSignature annotation
-            // acts like a classfile attribute.
-            if (!c.type.isErroneous() &&
-                types.isSameType(c.type, syms.polymorphicSignatureType)) {
-                if (!target.hasMethodHandles()) {
-                    // Somebody is compiling JDK7 source code to a JDK6 target.
-                    // Make it an error, since it is unlikely but important.
-                    log.error(env.tree.pos(),
-                            "wrong.target.for.polymorphic.signature.definition",
-                            target.name);
-                }
-                // Pull the flag through for better diagnostics, even on a bad target.
-                s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
-            }
             if (!annotated.add(a.type.tsym))
                 log.error(a.pos, "duplicate.annotation");
         }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Apr 09 21:58:05 2012 -0700
@@ -29,6 +29,8 @@
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.Attr.ResultInfo;
+import com.sun.tools.javac.comp.Check.CheckContext;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
@@ -70,6 +72,7 @@
     Names names;
     Log log;
     Symtab syms;
+    Attr attr;
     Check chk;
     Infer infer;
     ClassReader reader;
@@ -101,6 +104,7 @@
 
         names = Names.instance(context);
         log = Log.instance(context);
+        attr = Attr.instance(context);
         chk = Check.instance(context);
         infer = Infer.instance(context);
         reader = ClassReader.instance(context);
@@ -395,7 +399,6 @@
         else {
             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
             return (s2 == null || s2 == sym || sym.owner == s2.owner ||
-                    s2.isPolymorphicSignatureGeneric() ||
                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
         }
     }
@@ -445,7 +448,6 @@
                         boolean useVarargs,
                         Warner warn)
         throws Infer.InferenceException {
-        boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
         if (useVarargs && (m.flags() & VARARGS) == 0)
             throw inapplicableMethodException.setMessage();
         Type mt = types.memberType(site, m);
@@ -486,8 +488,7 @@
         }
 
         // find out whether we need to go the slow route via infer
-        boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
-                polymorphicSignature;
+        boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
         for (List<Type> l = argtypes;
              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
              l = l.tail) {
@@ -495,9 +496,7 @@
         }
 
         if (instNeeded)
-            return polymorphicSignature ?
-                infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
-                infer.instantiateMethod(env,
+            return infer.instantiateMethod(env,
                                     tvars,
                                     (MethodType)mt,
                                     m,
@@ -627,15 +626,8 @@
         }
 
         while (argtypes.nonEmpty() && formals.head != varargsFormal) {
-            Type undetFormal = infer.asUndetType(formals.head, undetvars);
-            Type capturedActual = types.capture(argtypes.head);
-            boolean works = allowBoxing ?
-                    types.isConvertible(capturedActual, undetFormal, warn) :
-                    types.isSubtypeUnchecked(capturedActual, undetFormal, warn);
-            if (!works) {
-                throw handler.argumentMismatch(false, argtypes.head, formals.head);
-            }
-            checkedArgs.append(capturedActual);
+            ResultInfo resultInfo = methodCheckResult(formals.head, allowBoxing, false, undetvars, handler, warn);
+            checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
             argtypes = argtypes.tail;
             formals = formals.tail;
         }
@@ -648,13 +640,9 @@
             //note: if applicability check is triggered by most specific test,
             //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
             Type elt = types.elemtype(varargsFormal);
-            Type eltUndet = infer.asUndetType(elt, undetvars);
             while (argtypes.nonEmpty()) {
-                Type capturedActual = types.capture(argtypes.head);
-                if (!types.isConvertible(capturedActual, eltUndet, warn)) {
-                    throw handler.argumentMismatch(true, argtypes.head, elt);
-                }
-                checkedArgs.append(capturedActual);
+                ResultInfo resultInfo = methodCheckResult(elt, allowBoxing, true, undetvars, handler, warn);
+                checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
                 argtypes = argtypes.tail;
             }
             //check varargs element type accessibility
@@ -665,39 +653,116 @@
         }
         return checkedArgs.toList();
     }
-    // where
-        public static class InapplicableMethodException extends RuntimeException {
-            private static final long serialVersionUID = 0;
 
-            JCDiagnostic diagnostic;
-            JCDiagnostic.Factory diags;
+    /**
+     * Check context to be used during method applicability checks. A method check
+     * context might contain inference variables.
+     */
+    abstract class MethodCheckContext implements CheckContext {
 
-            InapplicableMethodException(JCDiagnostic.Factory diags) {
-                this.diagnostic = null;
-                this.diags = diags;
+        MethodCheckHandler handler;
+        boolean useVarargs;
+        List<Type> undetvars;
+        Warner rsWarner;
+
+        public MethodCheckContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
+            this.handler = handler;
+            this.useVarargs = useVarargs;
+            this.undetvars = undetvars;
+            this.rsWarner = rsWarner;
+        }
+
+        public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
+            throw handler.argumentMismatch(useVarargs, found, req);
+        }
+
+        public Type rawInstantiatePoly(ForAll found, Type req, Warner warn) {
+            throw new AssertionError("ForAll in argument position");
+        }
+
+        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
+            return rsWarner;
+        }
+    }
+
+    /**
+     * Subclass of method check context class that implements strict method conversion.
+     * Strict method conversion checks compatibility between types using subtyping tests.
+     */
+    class StrictMethodContext extends MethodCheckContext {
+
+        public StrictMethodContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
+            super(handler, useVarargs, undetvars, rsWarner);
+        }
+
+        public boolean compatible(Type found, Type req, Warner warn) {
+            return types.isSubtypeUnchecked(found, infer.asUndetType(req, undetvars), warn);
+        }
+    }
+
+    /**
+     * Subclass of method check context class that implements loose method conversion.
+     * Loose method conversion checks compatibility between types using method conversion tests.
+     */
+    class LooseMethodContext extends MethodCheckContext {
+
+        public LooseMethodContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
+            super(handler, useVarargs, undetvars, rsWarner);
+        }
+
+        public boolean compatible(Type found, Type req, Warner warn) {
+            return types.isConvertible(found, infer.asUndetType(req, undetvars), warn);
+        }
+    }
+
+    /**
+     * Create a method check context to be used during method applicability check
+     */
+    ResultInfo methodCheckResult(Type to, boolean allowBoxing, boolean useVarargs,
+            List<Type> undetvars, MethodCheckHandler methodHandler, Warner rsWarner) {
+        MethodCheckContext checkContext = allowBoxing ?
+                new LooseMethodContext(methodHandler, useVarargs, undetvars, rsWarner) :
+                new StrictMethodContext(methodHandler, useVarargs, undetvars, rsWarner);
+        return attr.new ResultInfo(VAL, to, checkContext) {
+            @Override
+            protected Type check(DiagnosticPosition pos, Type found) {
+                return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found))));
             }
-            InapplicableMethodException setMessage() {
-                this.diagnostic = null;
-                return this;
-            }
-            InapplicableMethodException setMessage(String key) {
-                this.diagnostic = key != null ? diags.fragment(key) : null;
-                return this;
-            }
-            InapplicableMethodException setMessage(String key, Object... args) {
-                this.diagnostic = key != null ? diags.fragment(key, args) : null;
-                return this;
-            }
-            InapplicableMethodException setMessage(JCDiagnostic diag) {
-                this.diagnostic = diag;
-                return this;
-            }
+        };
+    }
 
-            public JCDiagnostic getDiagnostic() {
-                return diagnostic;
-            }
+    public static class InapplicableMethodException extends RuntimeException {
+        private static final long serialVersionUID = 0;
+
+        JCDiagnostic diagnostic;
+        JCDiagnostic.Factory diags;
+
+        InapplicableMethodException(JCDiagnostic.Factory diags) {
+            this.diagnostic = null;
+            this.diags = diags;
         }
-        private final InapplicableMethodException inapplicableMethodException;
+        InapplicableMethodException setMessage() {
+            this.diagnostic = null;
+            return this;
+        }
+        InapplicableMethodException setMessage(String key) {
+            this.diagnostic = key != null ? diags.fragment(key) : null;
+            return this;
+        }
+        InapplicableMethodException setMessage(String key, Object... args) {
+            this.diagnostic = key != null ? diags.fragment(key, args) : null;
+            return this;
+        }
+        InapplicableMethodException setMessage(JCDiagnostic diag) {
+            this.diagnostic = diag;
+            return this;
+        }
+
+        public JCDiagnostic getDiagnostic() {
+            return diagnostic;
+        }
+    }
+    private final InapplicableMethodException inapplicableMethodException;
 
 /* ***************************************************************************
  *  Symbol lookup
@@ -1670,25 +1735,18 @@
                 steps = steps.tail;
             }
             if (sym.kind >= AMBIGUOUS) {
-                if (site.tsym.isPolymorphicSignatureGeneric()) {
-                    //polymorphic receiver - synthesize new method symbol
+                //if nothing is found return the 'first' error
+                MethodResolutionPhase errPhase =
+                        currentResolutionContext.firstErroneousResolutionPhase();
+                sym = access(currentResolutionContext.resolutionCache.get(errPhase),
+                        pos, location, site, name, true, argtypes, typeargtypes);
+                env.info.varArgs = errPhase.isVarargsRequired;
+            } else if (allowMethodHandles) {
+                MethodSymbol msym = (MethodSymbol)sym;
+                if (msym.isSignaturePolymorphic(types)) {
                     env.info.varArgs = false;
-                    sym = findPolymorphicSignatureInstance(env,
-                            site, name, null, argtypes);
+                    return findPolymorphicSignatureInstance(env, sym, argtypes);
                 }
-                else {
-                    //if nothing is found return the 'first' error
-                    MethodResolutionPhase errPhase =
-                            currentResolutionContext.firstErroneousResolutionPhase();
-                    sym = access(currentResolutionContext.resolutionCache.get(errPhase),
-                            pos, location, site, name, true, argtypes, typeargtypes);
-                    env.info.varArgs = errPhase.isVarargsRequired;
-                }
-            } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
-                //non-instantiated polymorphic signature - synthesize new method symbol
-                env.info.varArgs = false;
-                sym = findPolymorphicSignatureInstance(env,
-                        site, name, (MethodSymbol)sym, argtypes);
             }
             return sym;
         }
@@ -1701,40 +1759,25 @@
      *  Searches in a side table, not the main scope of the site.
      *  This emulates the lookup process required by JSR 292 in JVM.
      *  @param env       Attribution environment
-     *  @param site      The original type from where the selection takes place.
-     *  @param name      The method's name.
-     *  @param spMethod  A template for the implicit method, or null.
-     *  @param argtypes  The required argument types.
-     *  @param typeargtypes  The required type arguments.
+     *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
+     *  @param argtypes  The required argument types
      */
-    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
-                                            Name name,
-                                            MethodSymbol spMethod,  // sig. poly. method or null if none
+    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
+                                            Symbol spMethod,
                                             List<Type> argtypes) {
         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
-                site, name, spMethod, argtypes);
-        long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
-                    (spMethod != null ?
-                        spMethod.flags() & Flags.AccessFlags :
-                        Flags.PUBLIC | Flags.STATIC);
-        Symbol m = null;
-        for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
-             e.scope != null;
-             e = e.next()) {
-            Symbol sym = e.sym;
-            if (types.isSameType(mtype, sym.type) &&
-                (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
-                types.isSameType(sym.owner.type, site)) {
-               m = sym;
-               break;
+                (MethodSymbol)spMethod, argtypes);
+        for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
+            if (types.isSameType(mtype, sym.type)) {
+               return sym;
             }
         }
-        if (m == null) {
-            // create the desired method
-            m = new MethodSymbol(flags, name, mtype, site.tsym);
-            polymorphicSignatureScope.enter(m);
-        }
-        return m;
+
+        // create the desired method
+        long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
+        Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner);
+        polymorphicSignatureScope.enter(msym);
+        return msym;
     }
 
     /** Resolve a qualified method identifier, throw a fatal error if not
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Apr 09 21:58:05 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1320,10 +1320,6 @@
                     sym.flags_field |= PROPRIETARY;
                 else
                     proxies.append(proxy);
-                if (majorVersion >= V51.major &&
-                    proxy.type.tsym == syms.polymorphicSignatureType.tsym) {
-                    sym.flags_field |= POLYMORPHIC_SIGNATURE;
-                }
             }
             annotate.later(new AnnotationCompleter(sym, proxies.toList()));
         }
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Apr 09 21:58:05 2012 -0700
@@ -983,12 +983,13 @@
                                 t = lambdaExpressionOrStatement(variableDeclaratorId(mods, t), pos);
                                 break;
                             }
-                        } else {
-                            Assert.check((mode & EXPR) != 0);
+                        } else if ((mode & EXPR) != 0) {
                             mode = EXPR;
                             JCExpression e = term2Rest(t1, TreeInfo.shiftPrec);
                             t = F.at(pos1).Binary(op, t, e);
                             t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
+                        } else {
+                            accept(GT);
                         }
                     } else if ((mode & TYPE) != 0 &&
                             (token.kind == IDENTIFIER || token.kind == ELLIPSIS)) {
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Apr 09 21:58:05 2012 -0700
@@ -134,12 +134,6 @@
 compiler.err.array.req.but.found=\
     array required, but {0} found
 
-compiler.err.assignment.from.super-bound=\
-    assigning from wildcard {0}
-
-compiler.err.assignment.to.extends-bound=\
-    assigning to wildcard {0}
-
 compiler.err.attribute.value.must.be.constant=\
     attribute value must be constant
 
@@ -223,9 +217,6 @@
 compiler.err.no.superclass=\
     {0} has no superclass
 
-compiler.err.wrong.target.for.polymorphic.signature.definition=\
-    MethodHandle API building requires -target 7 runtimes or better; current is -target {0}
-
 # 0: symbol, 1: type, 2: symbol, 3: type, 4: unused
 compiler.err.concrete.inheritance.conflict=\
     methods {0} from {1} and {2} from {3} are inherited with the same signature
@@ -779,25 +770,23 @@
 compiler.err.undef.label=\
     undefined label: {0}
 
-compiler.err.undetermined.type=\
-    cannot infer type arguments for {0}
-
-# 0: type, 1: message segment
-compiler.err.undetermined.type.1=\
-    cannot infer type arguments for {0};\n\
+# 0: list of type, 1: message segment
+compiler.misc.invalid.inferred.types=\
+    invalid inferred types for {0}\n\
     reason: {1}
 
-# 0: list of type, 1: message segment
-compiler.err.invalid.inferred.types=\
-    invalid inferred types for {0}; {1}
-
 # 0: message segment, 1: unused
 compiler.err.cant.apply.diamond=\
     cannot infer type arguments for {0}
 
 # 0: message segment or type, 1: message segment
 compiler.err.cant.apply.diamond.1=\
-    cannot infer type arguments for {0};\n\
+    cannot infer type arguments for {0}\n\
+    reason: {1}
+
+# 0: message segment or type, 1: message segment
+compiler.misc.cant.apply.diamond.1=\
+    cannot infer type arguments for {0}\n\
     reason: {1}
 
 compiler.err.unreachable.stmt=\
@@ -1503,11 +1492,15 @@
 
 #####
 
-# 0: message segment, 1: type, 2: type
+# 0: type, 1: type
 compiler.err.prob.found.req=\
-    {0}\n\
-    required: {2}\n\
-    found:    {1}
+    incompatible types\n\
+    required: {1}\n\
+    found: {0}
+
+# 0: message segment
+compiler.err.prob.found.req.1=\
+    incompatible types: {0}
 
 # 0: message segment, 1: type, 2: type
 compiler.warn.prob.found.req=\
@@ -1515,22 +1508,9 @@
     required: {2}\n\
     found:    {1}
 
-compiler.err.prob.found.req.1=\
-    {0} {3}\n\
-    required: {2}\n\
-    found:    {1}
-
-## The following are all possible strings for the first argument ({0}) of the
-## above strings.
-compiler.misc.incompatible.types=\
-    incompatible types
-
-# 0: message segment
-compiler.misc.incompatible.types.1=\
-    incompatible types; {0}
-
+# 0: type, 1: type
 compiler.misc.inconvertible.types=\
-    inconvertible types
+    {0} cannot be converted to {1}
 
 compiler.misc.possible.loss.of.precision=\
     possible loss of precision
@@ -1545,19 +1525,15 @@
 compiler.misc.unchecked.cast.to.type=\
     unchecked cast
 
-compiler.misc.assignment.from.super-bound=\
-    assignment from super-bound type {0}
-
-compiler.misc.assignment.to.extends-bound=\
-    assignment to extends-bound type {0}
-
 # compiler.err.star.expected=\
 #     ''*'' expected
 # compiler.err.no.elem.type=\
 #     \[\*\] cannot have a type
 
+# 0: type
 compiler.misc.try.not.applicable.to.type=\
-    try-with-resources not applicable to variable type
+    try-with-resources not applicable to variable type {0}\n\
+    (expected a variable of type java.lang.AutoCloseable)
 
 #####
 
@@ -1592,8 +1568,11 @@
 
 ## The following are all possible strings for the last argument of all those
 ## diagnostics whose key ends in ".1"
+
+# 0: type, 1: message segment
 compiler.misc.undetermined.type=\
-    undetermined type
+    cannot infer type arguments for {0}\n\
+    reason: {1}
 
 compiler.misc.type.variable.has.undetermined.type=\
     type variable {0} has undetermined type
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Apr 09 21:58:05 2012 -0700
@@ -1083,6 +1083,7 @@
         public List<JCCatch> catchers;
         public JCBlock finalizer;
         public List<JCTree> resources;
+        public boolean finallyCanCompleteNormally;
         protected JCTry(List<JCTree> resources,
                         JCBlock body,
                         List<JCCatch> catchers,
--- a/test/tools/javac/6979683/TestCast6979683_BAD34.java.errlog	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/6979683/TestCast6979683_BAD34.java.errlog	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-TestCast6979683_BAD34.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Number, boolean
+TestCast6979683_BAD34.java:34:49: compiler.err.prob.found.req: java.lang.Number, boolean
 1 error
--- a/test/tools/javac/6979683/TestCast6979683_BAD35.java.errlog	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/6979683/TestCast6979683_BAD35.java.errlog	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-TestCast6979683_BAD35.java:35:45: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Number, int
+TestCast6979683_BAD35.java:35:45: compiler.err.prob.found.req: java.lang.Number, int
 1 error
--- a/test/tools/javac/6979683/TestCast6979683_BAD36.java.errlog	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/6979683/TestCast6979683_BAD36.java.errlog	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-TestCast6979683_BAD36.java:36:58: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Comparable<java.lang.Integer>, int
+TestCast6979683_BAD36.java:36:58: compiler.err.prob.found.req: java.lang.Comparable<java.lang.Integer>, int
 1 error
--- a/test/tools/javac/6979683/TestCast6979683_BAD37.java.errlog	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/6979683/TestCast6979683_BAD37.java.errlog	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-TestCast6979683_BAD37.java:37:61: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), java.lang.Comparable<java.lang.Short>, int
+TestCast6979683_BAD37.java:37:61: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: java.lang.Comparable<java.lang.Short>, int)
 1 error
--- a/test/tools/javac/6979683/TestCast6979683_BAD38.java.errlog	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/6979683/TestCast6979683_BAD38.java.errlog	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-TestCast6979683_BAD38.java:38:62: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Comparable<java.lang.Character>, float
+TestCast6979683_BAD38.java:38:62: compiler.err.prob.found.req: java.lang.Comparable<java.lang.Character>, float
 1 error
--- a/test/tools/javac/6979683/TestCast6979683_BAD39.java.errlog	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/6979683/TestCast6979683_BAD39.java.errlog	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-TestCast6979683_BAD39.java:39:53: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), java.lang.Number, char
+TestCast6979683_BAD39.java:39:53: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: java.lang.Number, char)
 1 error
--- a/test/tools/javac/Diagnostics/6722234/T6722234d_1.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/Diagnostics/6722234/T6722234d_1.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,3 +1,3 @@
-T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types), compiler.misc.intersection.type: 1, T6722234d.A
+T6722234d.java:18:20: compiler.err.prob.found.req: compiler.misc.intersection.type: 1, T6722234d.A
 - compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, java.lang.Object,T6722234d.I1,T6722234d.I2)}
 1 error
--- a/test/tools/javac/Diagnostics/6722234/T6722234d_2.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/Diagnostics/6722234/T6722234d_2.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,3 +1,3 @@
-T6722234d.java:18:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types), compiler.misc.intersection.type: 1, T6722234d.A
+T6722234d.java:18:20: compiler.err.prob.found.req: compiler.misc.intersection.type: 1, T6722234d.A
 - compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, Object,I1,I2)}
 1 error
--- a/test/tools/javac/OverrideChecks/6400189/T6400189a.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/OverrideChecks/6400189/T6400189a.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,4 +1,4 @@
 T6400189a.java:14:35: compiler.warn.unchecked.call.mbr.of.raw.type: <T>getAnnotation(java.lang.Class<T>), java.lang.reflect.Constructor
-T6400189a.java:14:35: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.annotation.Annotation, java.lang.annotation.Documented
+T6400189a.java:14:35: compiler.err.prob.found.req: java.lang.annotation.Annotation, java.lang.annotation.Documented
 1 error
 1 warning
--- a/test/tools/javac/OverrideChecks/6400189/T6400189b.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/OverrideChecks/6400189/T6400189b.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,4 +1,4 @@
 T6400189b.java:24:24: compiler.warn.unchecked.call.mbr.of.raw.type: <T>m(T6400189b<T>), T6400189b.B
-T6400189b.java:24:24: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Object, java.lang.Integer
+T6400189b.java:24:24: compiler.err.prob.found.req: java.lang.Object, java.lang.Integer
 1 error
 1 warning
--- a/test/tools/javac/StringsInSwitch/BadlyTypedLabel1.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/StringsInSwitch/BadlyTypedLabel1.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: (compiler.misc.incompatible.types), int, java.lang.String
+BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: int, java.lang.String
 1 error
--- a/test/tools/javac/StringsInSwitch/BadlyTypedLabel2.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/StringsInSwitch/BadlyTypedLabel2.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-BadlyTypedLabel2.java:15:14: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.math.RoundingMode, java.lang.String
+BadlyTypedLabel2.java:15:14: compiler.err.prob.found.req: java.math.RoundingMode, java.lang.String
 1 error
--- a/test/tools/javac/T6326754.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/T6326754.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,6 +1,6 @@
 T6326754.java:44:12: compiler.err.name.clash.same.erasure: TestConstructor(T), TestConstructor(K)
 T6326754.java:52:17: compiler.err.name.clash.same.erasure: setT(K), setT(T)
-T6326754.java:64:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types), T, T
+T6326754.java:64:18: compiler.err.prob.found.req: T, T
 T6326754.java:70:11: compiler.err.cant.apply.symbol.1: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC<T>, (compiler.misc.arg.length.mismatch)
 - compiler.note.unchecked.filename: T6326754.java
 - compiler.note.unchecked.recompile
--- a/test/tools/javac/TryWithResources/TwrOnNonResource.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/TryWithResources/TwrOnNonResource.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,4 +1,4 @@
-TwrOnNonResource.java:12:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:15:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:18:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:12:30: compiler.err.prob.found.req.1: (compiler.misc.try.not.applicable.to.type: TwrOnNonResource)
+TwrOnNonResource.java:15:30: compiler.err.prob.found.req.1: (compiler.misc.try.not.applicable.to.type: TwrOnNonResource)
+TwrOnNonResource.java:18:30: compiler.err.prob.found.req.1: (compiler.misc.try.not.applicable.to.type: TwrOnNonResource)
 3 errors
--- a/test/tools/javac/cast/6270087/T6270087neg.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/6270087/T6270087neg.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6270087neg.java:36:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6270087neg.Foo<V>, T6270087neg.Foo<U>
+T6270087neg.java:36:29: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6270087neg.Foo<V>, T6270087neg.Foo<U>)
 1 error
--- a/test/tools/javac/cast/6557182/T6557182.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/6557182/T6557182.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,4 +1,4 @@
-T6557182.java:12:56: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T, java.lang.Comparable<java.lang.Integer>
+T6557182.java:12:56: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T, java.lang.Comparable<java.lang.Integer>)
 T6557182.java:16:56: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), T, java.lang.Comparable<java.lang.Integer>
 1 error
 1 warning
--- a/test/tools/javac/cast/6665356/T6665356.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/6665356/T6665356.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,8 +1,8 @@
-T6665356.java:31:55: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<java.lang.Long>
-T6665356.java:35:58: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.Number>
-T6665356.java:39:65: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>
-T6665356.java:43:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? extends java.lang.String>.Inner<java.lang.Long>
-T6665356.java:47:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? extends java.lang.String>
-T6665356.java:51:55: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.String>.Inner<java.lang.Long>
-T6665356.java:55:58: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.String>
+T6665356.java:31:55: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<java.lang.Long>)
+T6665356.java:35:58: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.Number>)
+T6665356.java:39:65: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>)
+T6665356.java:43:57: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? extends java.lang.String>.Inner<java.lang.Long>)
+T6665356.java:47:60: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? extends java.lang.String>)
+T6665356.java:51:55: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.String>.Inner<java.lang.Long>)
+T6665356.java:55:58: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.String>)
 7 errors
--- a/test/tools/javac/cast/6795580/T6795580.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/6795580/T6795580.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,8 +1,8 @@
-T6795580.java:31:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<java.lang.Long>[]
-T6795580.java:35:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.Number>[]
-T6795580.java:39:67: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>[]
-T6795580.java:43:59: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? extends java.lang.String>.Inner<java.lang.Long>[]
-T6795580.java:47:62: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? extends java.lang.String>[]
-T6795580.java:51:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.String>.Inner<java.lang.Long>[]
-T6795580.java:55:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.String>[]
+T6795580.java:31:57: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<java.lang.Long>[])
+T6795580.java:35:60: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.Number>[])
+T6795580.java:39:67: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>[])
+T6795580.java:43:59: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? extends java.lang.String>.Inner<java.lang.Long>[])
+T6795580.java:47:62: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? extends java.lang.String>[])
+T6795580.java:51:57: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.String>.Inner<java.lang.Long>[])
+T6795580.java:55:60: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.String>[])
 7 errors
--- a/test/tools/javac/cast/6932571/T6932571neg.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/6932571/T6932571neg.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6932571neg.java:39:19: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6932571neg.S, G
+T6932571neg.java:39:19: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T6932571neg.S, G)
 1 error
--- a/test/tools/javac/cast/7005095/T7005095neg.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/7005095/T7005095neg.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T7005095neg.java:13:25: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T7005095pos.FooImpl, T7005095pos.Foo<T>
+T7005095neg.java:13:25: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: T7005095pos.FooImpl, T7005095pos.Foo<T>)
 1 error
--- a/test/tools/javac/cast/7005671/T7005671.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/cast/7005671/T7005671.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,17 +1,17 @@
-T7005671.java:12:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), byte[], X[]
-T7005671.java:13:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), short[], X[]
-T7005671.java:14:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), int[], X[]
-T7005671.java:15:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), long[], X[]
-T7005671.java:16:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), float[], X[]
-T7005671.java:17:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), double[], X[]
-T7005671.java:18:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), char[], X[]
-T7005671.java:19:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), boolean[], X[]
-T7005671.java:23:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], byte[]
-T7005671.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], short[]
-T7005671.java:25:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], int[]
-T7005671.java:26:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], long[]
-T7005671.java:27:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], float[]
-T7005671.java:28:31: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], double[]
-T7005671.java:29:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], char[]
-T7005671.java:30:32: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), X[], boolean[]
+T7005671.java:12:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: byte[], X[])
+T7005671.java:13:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: short[], X[])
+T7005671.java:14:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: int[], X[])
+T7005671.java:15:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: long[], X[])
+T7005671.java:16:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: float[], X[])
+T7005671.java:17:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: double[], X[])
+T7005671.java:18:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: char[], X[])
+T7005671.java:19:26: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: boolean[], X[])
+T7005671.java:23:29: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], byte[])
+T7005671.java:24:30: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], short[])
+T7005671.java:25:28: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], int[])
+T7005671.java:26:29: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], long[])
+T7005671.java:27:30: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], float[])
+T7005671.java:28:31: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], double[])
+T7005671.java:29:29: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], char[])
+T7005671.java:30:32: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: X[], boolean[])
 16 errors
--- a/test/tools/javac/diags/examples.not-yet.txt	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples.not-yet.txt	Mon Apr 09 21:58:05 2012 -0700
@@ -1,8 +1,6 @@
 compiler.err.already.annotated                          # internal compiler error?
 compiler.err.already.defined.this.unit                  # seems to be masked by compiler.err.duplicate.class
 compiler.err.annotation.value.not.allowable.type        # cannot happen: precluded by complete type-specific tests
-compiler.err.assignment.from.super-bound                # DEAD
-compiler.err.assignment.to.extends-bound                # DEAD
 compiler.err.cant.apply.symbol
 compiler.err.cant.read.file                             # (apt.JavaCompiler?)
 compiler.err.cant.select.static.class.from.param.type
@@ -24,7 +22,6 @@
 compiler.err.no.encl.instance.of.type.in.scope          # cannot occur; always followed by assert false;
 compiler.err.no.match.entry                             # UNUSED?
 compiler.err.not.annotation.type                        # cannot occur given preceding checkType
-compiler.err.prob.found.req.1                           # Check: DEAD, in unused method
 compiler.err.proc.bad.config.file                       # JavacProcessingEnvironment
 compiler.err.proc.cant.access                           # completion failure
 compiler.err.proc.cant.access.1                         # completion failure, no stack trace
@@ -38,12 +35,8 @@
 compiler.err.stack.sim.error
 compiler.err.type.var.more.than.once                    # UNUSED
 compiler.err.type.var.more.than.once.in.result          # UNUSED
-compiler.err.undetermined.type
 compiler.err.unexpected.type
 compiler.err.unsupported.cross.fp.lit                   # Scanner: host system dependent
-compiler.err.wrong.target.for.polymorphic.signature.definition     # Transitional 292
-compiler.misc.assignment.from.super-bound
-compiler.misc.assignment.to.extends-bound
 compiler.misc.bad.class.file.header                     # bad class file
 compiler.misc.bad.class.signature                       # bad class file
 compiler.misc.bad.const.pool.tag                        # bad class file
@@ -88,7 +81,6 @@
 compiler.misc.type.variable.has.undetermined.type
 compiler.misc.unable.to.access.file                     # ClassFile
 compiler.misc.undecl.type.var                           # ClassReader
-compiler.misc.undetermined.type
 compiler.misc.unicode.str.not.supported                 # ClassReader
 compiler.misc.verbose.retro                             # UNUSED
 compiler.misc.verbose.retro.with                        # UNUSED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/CantApplyDiamond1.java	Mon Apr 09 21:58:05 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.prob.found.req.1
+// key: compiler.misc.cant.apply.diamond.1
+// key: compiler.misc.infer.no.conforming.instance.exists
+// key: compiler.misc.diamond
+
+class CantApplyDiamond1<X> {
+
+    CantApplyDiamond1(CantApplyDiamond1<? super X> lz) { }
+
+    void test(CantApplyDiamond1<Integer> li) {
+       CantApplyDiamond1<String> ls = new CantApplyDiamond1<>(li);
+    }
+}
--- a/test/tools/javac/diags/examples/IncompatibleTypes1.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/IncompatibleTypes1.java	Mon Apr 09 21:58:05 2012 -0700
@@ -21,9 +21,8 @@
  * questions.
  */
 
-// key: compiler.misc.incompatible.types.1
 // key: compiler.misc.infer.no.conforming.instance.exists
-// key: compiler.err.prob.found.req
+// key: compiler.err.prob.found.req.1
 
 class IncompatibleTypes1<V> {
     <T extends Integer & Runnable> IncompatibleTypes1<T> m() {
--- a/test/tools/javac/diags/examples/InconvertibleTypes.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/InconvertibleTypes.java	Mon Apr 09 21:58:05 2012 -0700
@@ -22,7 +22,7 @@
  */
 
 // key: compiler.misc.inconvertible.types
-// key: compiler.err.prob.found.req
+// key: compiler.err.prob.found.req.1
 
 class InconvertibleTypes {
     class Outer<S> {
--- a/test/tools/javac/diags/examples/InvalidInferredTypes.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/InvalidInferredTypes.java	Mon Apr 09 21:58:05 2012 -0700
@@ -21,7 +21,8 @@
  * questions.
  */
 
-// key: compiler.err.invalid.inferred.types
+// key: compiler.err.prob.found.req.1
+// key: compiler.misc.invalid.inferred.types
 // key: compiler.misc.inferred.do.not.conform.to.bounds
 
 import java.util.*;
--- a/test/tools/javac/diags/examples/PossibleLossPrecision.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/PossibleLossPrecision.java	Mon Apr 09 21:58:05 2012 -0700
@@ -22,7 +22,7 @@
  */
 
 // key: compiler.misc.possible.loss.of.precision
-// key: compiler.err.prob.found.req
+// key: compiler.err.prob.found.req.1
 
 class PossibleLossPrecision {
     long l;
--- a/test/tools/javac/diags/examples/ResourceNotApplicableToType.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/ResourceNotApplicableToType.java	Mon Apr 09 21:58:05 2012 -0700
@@ -22,7 +22,7 @@
  */
 
 // key: compiler.misc.try.not.applicable.to.type
-// key: compiler.err.prob.found.req
+// key: compiler.err.prob.found.req.1
 
 class ResourceNotApplicableToType {
     void m() {
--- a/test/tools/javac/diags/examples/UndeterminedType1.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/UndeterminedType1.java	Mon Apr 09 21:58:05 2012 -0700
@@ -21,7 +21,8 @@
  * questions.
  */
 
-// key: compiler.err.undetermined.type.1
+// key: compiler.err.prob.found.req.1
+// key: compiler.misc.undetermined.type
 // key: compiler.misc.no.unique.maximal.instance.exists
 
 class UndeterminedType1<V> {
--- a/test/tools/javac/diags/examples/WhereIntersection.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/diags/examples/WhereIntersection.java	Mon Apr 09 21:58:05 2012 -0700
@@ -24,7 +24,6 @@
 // key: compiler.misc.where.intersection
 // key: compiler.misc.where.description.intersection
 // key: compiler.misc.intersection.type
-// key: compiler.misc.incompatible.types
 // key: compiler.err.prob.found.req
 // options: -XDdiags=where
 // run: simple
--- a/test/tools/javac/generics/6207386/T6207386.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/6207386/T6207386.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6207386.java:13:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types), X, T6207386.F<? super X>
+T6207386.java:13:30: compiler.err.prob.found.req: X, T6207386.F<? super X>
 1 error
--- a/test/tools/javac/generics/diamond/neg/Neg05.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/diamond/neg/Neg05.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,19 +1,19 @@
 Neg05.java:19:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:19:35: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>
+Neg05.java:19:35: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>
 Neg05.java:20:58: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:20:45: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>
+Neg05.java:20:45: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>
 Neg05.java:21:43: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:21:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>
+Neg05.java:21:30: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>
 Neg05.java:22:56: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:22:43: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>
+Neg05.java:22:43: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>
 Neg05.java:24:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:24:35: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>
+Neg05.java:24:35: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<java.lang.String>
 Neg05.java:25:58: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:25:45: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>
+Neg05.java:25:45: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? extends java.lang.String>
 Neg05.java:26:43: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:26:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>
+Neg05.java:26:30: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<?>
 Neg05.java:27:56: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:27:43: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>
+Neg05.java:27:43: compiler.err.prob.found.req: Neg05.Foo<java.lang.String>, Neg05<?>.Foo<? super java.lang.String>
 Neg05.java:31:37: compiler.err.improperly.formed.type.inner.raw.param
 Neg05.java:32:47: compiler.err.improperly.formed.type.inner.raw.param
 Neg05.java:33:32: compiler.err.improperly.formed.type.inner.raw.param
--- a/test/tools/javac/generics/diamond/neg/Neg06.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/diamond/neg/Neg06.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-Neg06.java:16:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>)
+Neg06.java:16:37: compiler.err.prob.found.req.1: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>))
 1 error
--- a/test/tools/javac/generics/diamond/neg/Neg10.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/diamond/neg/Neg10.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-Neg10.java:16:22: compiler.err.prob.found.req: (compiler.misc.incompatible.types), Neg10.Foo<java.lang.Integer>, Neg10.Foo<java.lang.Number>
+Neg10.java:16:22: compiler.err.prob.found.req: Neg10.Foo<java.lang.Integer>, Neg10.Foo<java.lang.Number>
 1 error
--- a/test/tools/javac/generics/inference/6315770/T6315770.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/inference/6315770/T6315770.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,3 +1,3 @@
-T6315770.java:16:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
+T6315770.java:16:42: compiler.err.prob.found.req.1: (compiler.misc.undetermined.type: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable))
+T6315770.java:17:40: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)
 2 errors
--- a/test/tools/javac/generics/inference/6638712/T6638712b.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/inference/6638712/T6638712b.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)), <T>T, java.lang.String
+T6638712b.java:14:21: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)
 1 error
--- a/test/tools/javac/generics/inference/6638712/T6638712e.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/inference/6638712/T6638712e.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)), <X>T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>
+T6638712e.java:17:27: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)
 1 error
--- a/test/tools/javac/generics/inference/6650759/T6650759m.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/inference/6650759/T6650759m.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6650759m.java:43:36: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.util.List<? super java.lang.Integer>, java.util.List<? super java.lang.String>
+T6650759m.java:43:36: compiler.err.prob.found.req: java.util.List<? super java.lang.Integer>, java.util.List<? super java.lang.String>
 1 error
--- a/test/tools/javac/generics/rawOverride/7062745/T7062745neg.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/rawOverride/7062745/T7062745neg.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T7062745neg.java:16:36: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Object, java.lang.Number
+T7062745neg.java:16:36: compiler.err.prob.found.req: java.lang.Object, java.lang.Number
 1 error
--- a/test/tools/javac/generics/wildcards/6886247/T6886247_2.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/generics/wildcards/6886247/T6886247_2.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-T6886247_2.java:35:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types), compiler.misc.type.captureof: 1, ?, E
+T6886247_2.java:35:28: compiler.err.prob.found.req: compiler.misc.type.captureof: 1, ?, E
 1 error
--- a/test/tools/javac/multicatch/Neg06.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/multicatch/Neg06.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,3 +1,3 @@
-Neg06.java:14:16: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.String, java.lang.Throwable
-Neg06.java:14:25: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Integer, java.lang.Throwable
+Neg06.java:14:16: compiler.err.prob.found.req: java.lang.String, java.lang.Throwable
+Neg06.java:14:25: compiler.err.prob.found.req: java.lang.Integer, java.lang.Throwable
 2 errors
--- a/test/tools/javac/multicatch/Neg07.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/multicatch/Neg07.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-Neg07.java:14:56: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Class<compiler.misc.type.captureof: 1, ? extends Neg07.ParentException>, java.lang.Class<? extends Neg07.HasFoo>
+Neg07.java:14:56: compiler.err.prob.found.req: java.lang.Class<compiler.misc.type.captureof: 1, ? extends Neg07.ParentException>, java.lang.Class<? extends Neg07.HasFoo>
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/parser/7157165/T7157165.java	Mon Apr 09 21:58:05 2012 -0700
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7157165
+ *
+ * @summary Regression: code with disjunctive type crashes javac
+ * @compile/fail/ref=T7157165.out -XDrawDiagnostics T7157165.java
+ *
+ */
+
+class T7157165 {
+    Foo<? extends A|B> foo1 = null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/parser/7157165/T7157165.out	Mon Apr 09 21:58:05 2012 -0700
@@ -0,0 +1,4 @@
+T7157165.java:11:20: compiler.err.expected: >
+T7157165.java:11:21: compiler.err.expected: ';'
+T7157165.java:11:22: compiler.err.illegal.start.of.type
+3 errors
--- a/test/tools/javac/processing/TestWarnErrorCount.java	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/processing/TestWarnErrorCount.java	Mon Apr 09 21:58:05 2012 -0700
@@ -327,7 +327,7 @@
             Writer out = fo.openWriter();
             try {
                 out.write("class " + name + " {\n"
-                        + (warn ? "    int i = (int) 0;\n" : "")
+                        + (warn ? "    void m() throws Exception { try (AutoCloseable ac = null) { } }" : "")
                         + (error ? "   ERROR\n" : "")
                         + "}\n");
             } finally {
--- a/test/tools/javac/types/CastObjectToPrimitiveTest.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/types/CastObjectToPrimitiveTest.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,2 +1,2 @@
-CastObjectToPrimitiveTest.java:36:23: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), java.lang.Object, int
+CastObjectToPrimitiveTest.java:36:23: compiler.err.prob.found.req.1: (compiler.misc.inconvertible.types: java.lang.Object, int)
 1 error
--- a/test/tools/javac/varargs/6313164/T6313164.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/varargs/6313164/T6313164.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,6 +1,6 @@
 T6313164.java:12:8: compiler.err.cant.apply.symbol.1: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
-T6313164.java:14:13: compiler.err.invalid.inferred.types: X, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
-T6313164.java:15:13: compiler.err.invalid.inferred.types: X, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
+T6313164.java:14:13: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: X, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164))
+T6313164.java:15:13: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: X, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164))
 - compiler.note.unchecked.filename: B.java
 - compiler.note.unchecked.recompile
 3 errors
--- a/test/tools/javac/varargs/7097436/T7097436.out	Thu Apr 05 13:05:08 2012 -0700
+++ b/test/tools/javac/varargs/7097436/T7097436.out	Mon Apr 09 21:58:05 2012 -0700
@@ -1,6 +1,6 @@
 T7097436.java:13:20: compiler.warn.varargs.unsafe.use.varargs.param: ls
 T7097436.java:14:25: compiler.warn.varargs.unsafe.use.varargs.param: ls
-T7097436.java:15:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.util.List<java.lang.String>[], java.lang.String
-T7097436.java:16:26: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.util.List<java.lang.String>[], java.lang.Integer[]
+T7097436.java:15:20: compiler.err.prob.found.req: java.util.List<java.lang.String>[], java.lang.String
+T7097436.java:16:26: compiler.err.prob.found.req: java.util.List<java.lang.String>[], java.lang.Integer[]
 2 errors
 2 warnings