changeset 2123:242015274be2 jdk7u80-b14

Merge
author asaha
date Mon, 16 Mar 2015 11:03:41 -0700
parents 85832379d0f9 (diff) 79923da8c058 (current diff)
children 0853c09a66af
files .hgtags
diffstat 25 files changed, 1172 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Mar 16 10:49:12 2015 -0700
+++ b/.hgtags	Mon Mar 16 11:03:41 2015 -0700
@@ -577,3 +577,17 @@
 a5f2b51a4ea77cd5471d03501a460c80b375379a jdk7u79-b12
 525562d90c3c06ddc9ef6c266db2d2aa8177b7e0 jdk7u79-b13
 185113eafdbffa675b5db5859ccdd16cfd19ae6f jdk7u79-b14
+772aad4e9681828b8ee193b9ed971cbfe6c7f347 jdk7u80-b00
+6c307a0b7a94e002d8a2532ffd8146d6c53f42d3 jdk7u80-b01
+5bd6f3adf690dc2de8881b6f9f48336db4af7865 jdk7u80-b02
+bcbd241df6cd0a643480c8de183c541a662dd506 jdk7u80-b03
+04b56f4312b62d8bdf4eb1159132de8437994d34 jdk7u80-b04
+f40fb76025c798cab4fb0e1966be1bceb8234527 jdk7u80-b05
+335ee524dc68a42863f3fa3f081b781586e7ba2d jdk7u80-b06
+6f7b359c4e9f82cbd399edc93c3275c3e668d2ea jdk7u80-b07
+e6db2a97b3696fb5e7786b23f77af346a935a370 jdk7u80-b08
+88b7f1ad17d20eace30d0ab83d4e7413c0c863ff jdk7u80-b09
+55f4bb77c71c8e0b9be2ac6484c7a3838203d53a jdk7u80-b10
+ae5ecf167fb7d70f98aa117ea6a053307db98b14 jdk7u80-b11
+c084fb3e386393774886645aee8ef57b22854c08 jdk7u80-b12
+e6845c405f95b6336e000f054f87a964a33927d9 jdk7u80-b13
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Mar 16 11:03:41 2015 -0700
@@ -2400,9 +2400,9 @@
             }
         });
         for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
-             e != null;
-             e = e.sibling)
-            if (e.sym.kind == MTH)
+                e != null;
+                e = e.sibling)
+            if (e.sym.kind == MTH && e.sym.name != names.clinit)
                 members.add((MethodSymbol) e.sym);
 
         // count them off as they're annotated
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -223,6 +223,12 @@
                                                meth.name,
                                                bridgeType,
                                                origin);
+        /* once JDK-6996415 is solved it should be checked if this approach can
+         * be applied to method addOverrideBridgesIfNeeded
+         */
+        bridge.params = createBridgeParams(impl, bridge, bridgeType);
+        bridge.attributes_field = impl.attributes_field;
+
         if (!hypothetical) {
             JCMethodDecl md = make.MethodDef(bridge, null);
 
@@ -257,6 +263,26 @@
         overridden.put(bridge, meth);
     }
 
+    private List<VarSymbol> createBridgeParams(MethodSymbol impl, MethodSymbol bridge,
+            Type bridgeType) {
+        List<VarSymbol> bridgeParams = null;
+        if (impl.params != null) {
+            bridgeParams = List.nil();
+            List<VarSymbol> implParams = impl.params;
+            Type.MethodType mType = (Type.MethodType)bridgeType;
+            List<Type> argTypes = mType.argtypes;
+            while (implParams.nonEmpty() && argTypes.nonEmpty()) {
+                VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC | PARAMETER,
+                        implParams.head.name, argTypes.head, bridge);
+                param.attributes_field = implParams.head.attributes_field;
+                bridgeParams = bridgeParams.append(param);
+                implParams = implParams.tail;
+                argTypes = argTypes.tail;
+            }
+        }
+        return bridgeParams;
+    }
+
     /** Add bridge if given symbol is a non-private, non-static member
      *  of the given class, which is either defined in the class or non-final
      *  inherited, and one of the two following conditions holds:
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -1541,15 +1541,17 @@
             // The method wasn't found: emit a warning and recover
             JavaFileObject prevSource = log.useSource(requestingOwner.classfile);
             try {
-                if (failure == null) {
-                    log.warning("annotation.method.not.found",
-                                container,
-                                name);
-                } else {
-                    log.warning("annotation.method.not.found.reason",
-                                container,
-                                name,
-                                failure.getDetailValue());//diagnostic, if present
+                if (lintClassfile) {
+                    if (failure == null) {
+                        log.warning("annotation.method.not.found",
+                                    container,
+                                    name);
+                    } else {
+                        log.warning("annotation.method.not.found.reason",
+                                    container,
+                                    name,
+                                    failure.getDetailValue()); //diagnostic, if present
+                    }
                 }
             } finally {
                 log.useSource(prevSource);
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1012,25 +1012,29 @@
 
         if (code.varBufferSize > 0) {
             int alenIdx = writeAttr(names.LocalVariableTable);
-            databuf.appendChar(code.varBufferSize);
+            databuf.appendChar(code.getLVTSize());
 
             for (int i=0; i<code.varBufferSize; i++) {
                 Code.LocalVar var = code.varBuffer[i];
-
-                // write variable info
-                Assert.check(var.start_pc >= 0
-                        && var.start_pc <= code.cp);
-                databuf.appendChar(var.start_pc);
-                Assert.check(var.length >= 0
-                        && (var.start_pc + var.length) <= code.cp);
-                databuf.appendChar(var.length);
-                VarSymbol sym = var.sym;
-                databuf.appendChar(pool.put(sym.name));
-                Type vartype = sym.erasure(types);
-                if (needsLocalVariableTypeEntry(sym.type))
-                    nGenericVars++;
-                databuf.appendChar(pool.put(typeSig(vartype)));
-                databuf.appendChar(var.reg);
+                for (Code.LocalVar.Range r: var.aliveRanges) {
+                    // write variable info
+                    if (!(r.start_pc >= 0 && r.start_pc <= code.cp)) {
+                        throw new AssertionError();
+                    }
+                    databuf.appendChar(r.start_pc);
+                    if (!(r.length >= 0 && (r.start_pc + r.length) <= code.cp)) {
+                        throw new AssertionError();
+                    }
+                    databuf.appendChar(r.length);
+                    VarSymbol sym = var.sym;
+                    databuf.appendChar(pool.put(sym.name));
+                    Type vartype = sym.erasure(types);
+                    databuf.appendChar(pool.put(typeSig(vartype)));
+                    databuf.appendChar(var.reg);
+                    if (needsLocalVariableTypeEntry(var.sym.type)) {
+                        nGenericVars++;
+                    }
+                }
             }
             endAttr(alenIdx);
             acount++;
@@ -1046,13 +1050,15 @@
                 VarSymbol sym = var.sym;
                 if (!needsLocalVariableTypeEntry(sym.type))
                     continue;
-                count++;
-                // write variable info
-                databuf.appendChar(var.start_pc);
-                databuf.appendChar(var.length);
-                databuf.appendChar(pool.put(sym.name));
-                databuf.appendChar(pool.put(typeSig(sym.type)));
-                databuf.appendChar(var.reg);
+                for (Code.LocalVar.Range r : var.aliveRanges) {
+                    // write variable info
+                    databuf.appendChar(r.start_pc);
+                    databuf.appendChar(r.length);
+                    databuf.appendChar(pool.put(sym.name));
+                    databuf.appendChar(pool.put(typeSig(sym.type)));
+                    databuf.appendChar(var.reg);
+                    count++;
+                }
             }
             Assert.check(count == nGenericVars);
             endAttr(alenIdx);
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1151,7 +1151,9 @@
     public int entryPoint(State state) {
         int pc = curPc();
         alive = true;
-        this.state = state.dup();
+        State newState = state.dup();
+        setDefined(newState.defined);
+        this.state = newState;
         Assert.check(state.stacksize <= max_stack);
         if (debugCode) System.err.println("entry point " + state);
         pendingStackMap = needStackMap;
@@ -1164,7 +1166,9 @@
     public int entryPoint(State state, Type pushed) {
         int pc = curPc();
         alive = true;
-        this.state = state.dup();
+        State newState = state.dup();
+        setDefined(newState.defined);
+        this.state = newState;
         Assert.check(state.stacksize <= max_stack);
         this.state.push(pushed);
         if (debugCode) System.err.println("entry point " + state);
@@ -1452,6 +1456,10 @@
                 chain.pc + 3 == target && target == cp && !fixedPc) {
                 // If goto the next instruction, the jump is not needed:
                 // compact the code.
+                if (varDebugInfo) {
+                    adjustAliveRanges(cp, -3);
+                }
+
                 cp = cp - 3;
                 target = target - 3;
                 if (chain.next == null) {
@@ -1736,8 +1744,7 @@
                     sym = sym.clone(sym.owner);
                     sym.type = newtype;
                     LocalVar newlv = lvar[i] = new LocalVar(sym);
-                    // should the following be initialized to cp?
-                    newlv.start_pc = lv.start_pc;
+                    newlv.aliveRanges = lv.aliveRanges;
                 }
             }
         }
@@ -1825,18 +1832,118 @@
     static class LocalVar {
         final VarSymbol sym;
         final char reg;
-        char start_pc = Character.MAX_VALUE;
-        char length = Character.MAX_VALUE;
+
+        class Range {
+            char start_pc = Character.MAX_VALUE;
+            char length = Character.MAX_VALUE;
+
+            Range() {}
+
+            Range(char start) {
+                this.start_pc = start;
+            }
+
+            Range(char start, char length) {
+                this.start_pc = start;
+                this.length = length;
+            }
+
+            boolean closed() {
+                return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
+            }
+
+            @Override
+            public String toString() {
+                int currentStartPC = start_pc;
+                int currentLength = length;
+                return "startpc = " + currentStartPC + " length " + currentLength;
+            }
+        }
+
+        java.util.List<Range> aliveRanges = new java.util.ArrayList<Range>();
+
         LocalVar(VarSymbol v) {
             this.sym = v;
             this.reg = (char)v.adr;
         }
+
         public LocalVar dup() {
             return new LocalVar(sym);
         }
+
+        Range firstRange() {
+            return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
+        }
+
+        Range lastRange() {
+            return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
+        }
+
+        void removeLastRange() {
+            Range lastRange = lastRange();
+            if (lastRange != null) {
+                aliveRanges.remove(lastRange);
+            }
+        }
+
+        @Override
         public String toString() {
-            return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
+            if (aliveRanges == null) {
+                return "empty local var";
+            }
+            StringBuilder sb = new StringBuilder().append(sym)
+                    .append(" in register ").append((int)reg).append(" \n");
+            for (Range r : aliveRanges) {
+                sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
+                    .append(" length=").append(Integer.toString(((int)r.length)))
+                    .append("\n");
+            }
+            return sb.toString();
+        }
+
+        public void openRange(char start) {
+            if (!hasOpenRange()) {
+                aliveRanges.add(new Range(start));
+            }
         }
+
+        public void closeRange(char length) {
+            if (isLastRangeInitialized() && length > 0) {
+                Range range = lastRange();
+                if (range != null) {
+                    if (range.length == Character.MAX_VALUE) {
+                        range.length = length;
+                    }
+                }
+            } else {
+                removeLastRange();
+            }
+        }
+
+        public boolean hasOpenRange() {
+            if (aliveRanges.isEmpty()) {
+                return false;
+            }
+            return lastRange().length == Character.MAX_VALUE;
+        }
+
+        public boolean isLastRangeInitialized() {
+            if (aliveRanges.isEmpty()) {
+                return false;
+            }
+            return lastRange().start_pc != Character.MAX_VALUE;
+        }
+
+        public Range getWidestRange() {
+            if (aliveRanges.isEmpty()) {
+                return new Range();
+            } else {
+                Range firstRange = firstRange();
+                Range lastRange = lastRange();
+                char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
+                return new Range(firstRange.start_pc, length);
+            }
+         }
     };
 
     /** Local variables, indexed by register. */
@@ -1858,6 +1965,30 @@
         state.defined.excl(adr);
     }
 
+    void adjustAliveRanges(int oldCP, int delta) {
+        for (LocalVar localVar: lvar) {
+            if (localVar != null) {
+                for (LocalVar.Range range: localVar.aliveRanges) {
+                    if (range.closed() && range.start_pc + range.length >= oldCP) {
+                        range.length += delta;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Calculates the size of the LocalVariableTable.
+     */
+    public int getLVTSize() {
+        int result = varBufferSize;
+        for (int i = 0; i < varBufferSize; i++) {
+            LocalVar var = varBuffer[i];
+            result += var.aliveRanges.size() - 1;
+        }
+        return result;
+    }
+
     /** Set the current variable defined state. */
     public void setDefined(Bits newDefined) {
         if (alive && newDefined != state.defined) {
@@ -1883,8 +2014,7 @@
         } else {
             state.defined.incl(adr);
             if (cp < Character.MAX_VALUE) {
-                if (v.start_pc == Character.MAX_VALUE)
-                    v.start_pc = (char)cp;
+                v.openRange((char)cp);
             }
         }
     }
@@ -1894,15 +2024,15 @@
         state.defined.excl(adr);
         if (adr < lvar.length &&
             lvar[adr] != null &&
-            lvar[adr].start_pc != Character.MAX_VALUE) {
+            lvar[adr].isLastRangeInitialized()) {
             LocalVar v = lvar[adr];
-            char length = (char)(curPc() - v.start_pc);
+            char length = (char)(curPc()- v.lastRange().start_pc);
             if (length > 0 && length < Character.MAX_VALUE) {
                 lvar[adr] = v.dup();
-                v.length = length;
+                v.closeRange(length);
                 putVar(v);
             } else {
-                v.start_pc = Character.MAX_VALUE;
+                v.removeLastRange();
             }
         }
     }
@@ -1912,10 +2042,10 @@
         LocalVar v = lvar[adr];
         if (v != null) {
             lvar[adr] = null;
-            if (v.start_pc != Character.MAX_VALUE) {
-                char length = (char)(curPc() - v.start_pc);
+            if (v.isLastRangeInitialized()) {
+                char length = (char)(curPc()- v.lastRange().start_pc);
                 if (length < Character.MAX_VALUE) {
-                    v.length = length;
+                    v.closeRange(length);
                     putVar(v);
                 }
             }
--- a/test/tools/javac/6889255/T6889255.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/test/tools/javac/6889255/T6889255.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -429,9 +429,9 @@
         // -- no Code attribute for the LocalVariableTable attribute
         if ((v.owner.flags() & Flags.ABSTRACT) != 0)
             return "arg" + (i - 1);
-        // bridge methods use xN
+        // bridge methods use argN. No LVT for them anymore
         if ((v.owner.flags() & Flags.BRIDGE) != 0)
-            return "x" + (i - 1);
+            return "arg" + (i - 1);
 
         // The rest of this method assumes the local conventions in the test program
         Type t = v.type;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/T6695379/AnnotationsAreNotCopiedToBridgeMethodsTest.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/*
+ * @test
+ * @bug 6695379
+ * @summary Copy method annotations and parameter annotations to synthetic
+ * bridge methods
+ * @run main AnnotationsAreNotCopiedToBridgeMethodsTest
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.io.BufferedInputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import com.sun.tools.classfile.AccessFlags;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.Attributes;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.util.Assert;
+
+public class AnnotationsAreNotCopiedToBridgeMethodsTest {
+
+    public static void main(String[] args) throws Exception {
+        new AnnotationsAreNotCopiedToBridgeMethodsTest().run();
+    }
+
+    void run() throws Exception {
+        checkClassFile(Paths.get(System.getProperty("test.classes"),
+                this.getClass().getSimpleName() + "$CovariantReturnType.class"));
+        checkClassFile(Paths.get(System.getProperty("test.classes"),
+                this.getClass().getSimpleName() +
+                "$CovariantReturnType$VisibilityChange.class"));
+    }
+
+    void checkClassFile(final Path cfilePath) throws Exception {
+        ClassFile classFile = ClassFile.read(
+                new BufferedInputStream(Files.newInputStream(cfilePath)));
+        for (Method method : classFile.methods) {
+            if (method.access_flags.is(AccessFlags.ACC_BRIDGE)) {
+                checkForAttr(method.attributes,
+                        "Annotations hasn't been copied to bridge method",
+                        Attribute.RuntimeVisibleAnnotations,
+                        Attribute.RuntimeVisibleParameterAnnotations);
+            }
+        }
+    }
+
+    void checkForAttr(Attributes attrs, String errorMsg, String... attrNames) {
+        for (String attrName : attrNames) {
+            Assert.checkNonNull(attrs.get(attrName), errorMsg);
+        }
+    }
+
+    @Target(value = {ElementType.PARAMETER})
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface ParamAnnotation {}
+
+    @Target(value = {ElementType.METHOD})
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface MethodAnnotation {}
+
+    abstract class T<A,B> {
+        B m(A a){return null;}
+    }
+
+    class CovariantReturnType extends T<Integer, Integer> {
+        @MethodAnnotation
+        Integer m(@ParamAnnotation Integer i) {
+            return i;
+        }
+
+        public class VisibilityChange extends CovariantReturnType {}
+
+    }
+
+}
--- a/test/tools/javac/annotations/6214965/T6214965.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/test/tools/javac/annotations/6214965/T6214965.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -23,9 +23,10 @@
 
 /**
  * @test
- * @bug     6214965 6365854
+ * @bug     6214965 6365854 8068639
  * @summary Compiler crash on redefing nested annotation types
  * @compile CompilerAnnotationTest.java CompilerAnnotationTest2.java
  * @compile CompilerAnnotationTest2bad.java
- * @compile/ref=T6214965.out -XDrawDiagnostics CompilerAnnotationTest2bad.java
+ * @compile/ref=T6214965.out -XDrawDiagnostics -Xlint:classfile CompilerAnnotationTest2bad.java
+ * @compile -Werror CompilerAnnotationTest2bad.java
  */
--- a/test/tools/javac/annotations/6365854/T6365854.java	Mon Mar 16 10:49:12 2015 -0700
+++ b/test/tools/javac/annotations/6365854/T6365854.java	Mon Mar 16 11:03:41 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug     6365854
+ * @bug     6365854 8068639
  * @summary javac crashes when compiling against an annotated class
  * @compile TestAnnotation.java TestCore.java
  * @clean test.annotation.TestAnnotation
@@ -33,11 +33,11 @@
  *
  * @compile TestAnnotation.java TestCore.java
  * @clean test.annotation.TestAnnotation
- * @compile/ref=test1.out -XDrawDiagnostics T6365854.java
+ * @compile/ref=test1.out -XDrawDiagnostics -Xlint:classfile T6365854.java
  * @run main T6365854
- * @compile/ref=test2.out -XDrawDiagnostics evolve/TestAnnotation.java T6365854.java
+ * @compile/ref=test2.out -XDrawDiagnostics -Xlint:classfile evolve/TestAnnotation.java T6365854.java
  * @run main T6365854
- * @compile/ref=test2.out -XDrawDiagnostics T6365854.java
+ * @compile/ref=test2.out -XDrawDiagnostics -Xlint:classfile T6365854.java
  * @run main T6365854
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/clinit/AnnoWithClinit1.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/*
+ * @test
+ * @bug 8013485
+ * @summary Annotations that gets a clinit can't be verified for correct elements in a second compilation unit
+ * @compile AnnoWithClinit1.java
+ */
+
+public @interface AnnoWithClinit1 {
+    Foo f = new Foo();
+
+    @AnnoWithClinit1
+    static class C {} // this is in the same CU so there wont be a
+                      // <clinit> when the this anno instance is checked
+
+    class Foo {}
+}
+
+
+@AnnoWithClinit1
+class BarAnnoClinit1 {}
+
+@interface AAnnoClinit1 {
+    Runnable r2 = new Runnable() { public void run() { }};
+    String str1();
+    String str2withdefault() default "bar";
+}
+
+@AAnnoClinit1(str1="value")
+class TestAnnoClinit1 { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/clinit/AnnoWithClinitFail.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/*
+ * @test
+ * @bug 8013485
+ * @summary Annotations that gets a clinit can't be verified for correct elements in a second compilation unit
+ * @compile/fail/ref=AnnoWithClinitFail.out -XDrawDiagnostics AnnoWithClinitFail.java
+ */
+
+public @interface AnnoWithClinitFail {
+    Foo f = new Foo();
+
+    String foo();
+    String bar() default "bar";
+
+    @AnnoWithClinitFail
+    static class C {} // this is in the same CU so there wont be a
+                      // <clinit> when the this anno instance is checked
+
+    class Foo {}
+}
+
+@AnnoWithClinitFail
+class TestAnnoWithClinitFail { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/clinit/AnnoWithClinitFail.out	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,3 @@
+AnnoWithClinitFail.java:37:5: compiler.err.annotation.missing.default.value: AnnoWithClinitFail, foo
+AnnoWithClinitFail.java:44:1: compiler.err.annotation.missing.default.value: AnnoWithClinitFail, foo
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/DARanges.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+import java.lang.annotation.*;
+
+@Target({ElementType.METHOD})
+@interface DARange {
+    String varName();
+    int bytecodeStart();
+    int bytecodeLength();
+}
+
+@Target({ElementType.METHOD})
+@interface DARanges {DARange[] value();}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/LVTHarness.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/*
+ * @test
+ * @bug 8058708
+ * @summary The LVT is not generated correctly during some try/catch scenarios
+ *          javac crash while creating LVT entry for a local variable defined in
+ *          an inner block
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor LVTHarness
+ * @run main LVTHarness
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ConstantPool.InvalidIndex;
+import com.sun.tools.classfile.ConstantPool.UnexpectedEntry;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.LocalVariableTable_attribute;
+import com.sun.tools.classfile.Method;
+
+import static javax.tools.StandardLocation.*;
+import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry;
+import static javax.tools.JavaFileObject.Kind.SOURCE;
+
+public class LVTHarness {
+
+    static int nerrors = 0;
+
+    static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+    static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+    public static void main(String[] args) throws Exception {
+
+        String testDir = System.getProperty("test.src");
+        fm.setLocation(SOURCE_PATH, Arrays.asList(new File(testDir, "tests")));
+
+        // Make sure classes are written to scratch dir.
+        fm.setLocation(CLASS_OUTPUT, Arrays.asList(new File(".")));
+
+        for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) {
+            new LVTHarness(jfo).check();
+        }
+        if (nerrors > 0) {
+            throw new AssertionError("Errors were found");
+        }
+    }
+
+
+    JavaFileObject jfo;
+    Map<ElementKey, DARanges> aliveRangeMap = new HashMap<ElementKey, DARanges>();
+    Set<String> declaredKeys = new HashSet<String>();
+    List<ElementKey> seenDARanges = new ArrayList<ElementKey>();
+
+    protected LVTHarness(JavaFileObject jfo) {
+        this.jfo = jfo;
+    }
+
+    protected void check() throws Exception {
+
+        JavacTask ct = (JavacTask) comp.getTask(null, fm, null, Arrays.asList("-g"),
+                                                null, Arrays.asList(jfo));
+        System.err.println("compiling code " + jfo);
+        ct.setProcessors(Collections.singleton(new DARangeFinder()));
+        if (!ct.call()) {
+            throw new AssertionError("Error during compilation");
+        }
+
+
+        File javaFile = new File(jfo.getName());
+        File classFile = new File(javaFile.getName().replace(".java", ".class"));
+        checkClassFile(classFile);
+
+        //check all candidates have been used up
+        for (Map.Entry<ElementKey, DARanges> entry : aliveRangeMap.entrySet()) {
+            if (!seenDARanges.contains(entry.getKey())) {
+                error("Redundant @DARanges annotation on method " +
+                        entry.getKey().elem + " with key " + entry.getKey());
+            }
+        }
+    }
+
+    void checkClassFile(File file)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        ClassFile classFile = ClassFile.read(file);
+        ConstantPool constantPool = classFile.constant_pool;
+
+        //lets get all the methods in the class file.
+        for (Method method : classFile.methods) {
+            for (ElementKey elementKey: aliveRangeMap.keySet()) {
+                String methodDesc = method.getName(constantPool) +
+                        method.descriptor.getParameterTypes(constantPool).replace(" ", "");
+                if (methodDesc.equals(elementKey.elem.toString())) {
+                    checkMethod(constantPool, method, aliveRangeMap.get(elementKey));
+                    seenDARanges.add(elementKey);
+                }
+            }
+        }
+    }
+
+    void checkMethod(ConstantPool constantPool, Method method, DARanges ranges)
+            throws InvalidIndex, UnexpectedEntry {
+        Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);
+        LocalVariableTable_attribute lvt =
+            (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable));
+        List<String> infoFromRanges = convertToStringList(ranges);
+        List<String> infoFromLVT = convertToStringList(constantPool, lvt);
+
+        // infoFromRanges most be contained in infoFromLVT
+        int i = 0;
+        int j = 0;
+        while (i < infoFromRanges.size() && j < infoFromLVT.size()) {
+            int comparison = infoFromRanges.get(i).compareTo(infoFromLVT.get(j));
+            if (comparison == 0) {
+                i++; j++;
+            } else if (comparison > 0) {
+                j++;
+            } else {
+                break;
+            }
+        }
+
+        if (i < infoFromRanges.size()) {
+            error(infoFromLVT, infoFromRanges);
+        }
+    }
+
+    List<String> convertToStringList(DARanges ranges) {
+        List<String> result = new ArrayList<String>();
+        for (Annotation anno : ranges.value()) {
+            DARange range = (DARange)anno;
+            String str = formatLocalVariableData(range.varName(),
+                    range.bytecodeStart(), range.bytecodeLength());
+            result.add(str);
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    List<String> convertToStringList(ConstantPool constantPool,
+            LocalVariableTable_attribute lvt) throws InvalidIndex, UnexpectedEntry {
+        List<String> result = new ArrayList<String>();
+        for (Entry entry : lvt.local_variable_table) {
+            String str = formatLocalVariableData(constantPool.getUTF8Value(entry.name_index),
+                    entry.start_pc, entry.length);
+            result.add(str);
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    String formatLocalVariableData(String varName, int start, int length) {
+        StringBuilder sb = new StringBuilder()
+                    .append("var name: ").append(varName)
+                    .append(" start: ").append(start)
+                    .append(" length: ").append(length);
+        return sb.toString();
+    }
+
+    protected void error(List<String> infoFromLVT, List<String> infoFromRanges) {
+        nerrors++;
+        System.err.printf("Error occurred while checking file: %s\n", jfo.getName());
+        System.err.println("The range info from the annotations is");
+        printStringListToErrOutput(infoFromRanges);
+        System.err.println();
+        System.err.println("And the range info from the class file is");
+        printStringListToErrOutput(infoFromLVT);
+        System.err.println();
+    }
+
+    void printStringListToErrOutput(List<String> list) {
+        for (String s : list) {
+            System.err.println("\t" + s);
+        }
+    }
+
+    protected void error(String msg) {
+        nerrors++;
+        System.err.printf("Error occurred while checking file: %s\nreason: %s\n",
+                jfo.getName(), msg);
+    }
+
+    class DARangeFinder extends JavacTestingAbstractProcessor {
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations,
+            RoundEnvironment roundEnv) {
+            if (roundEnv.processingOver())
+                return true;
+
+            TypeElement aliveRangeAnno = elements.getTypeElement("DARanges");
+
+            if (!annotations.contains(aliveRangeAnno)) {
+                error("no @DARanges annotation found in test class");
+            }
+
+            for (Element elem: roundEnv.getElementsAnnotatedWith(aliveRangeAnno)) {
+                Annotation annotation = elem.getAnnotation(DARanges.class);
+                aliveRangeMap.put(new ElementKey(elem), (DARanges)annotation);
+            }
+            return true;
+        }
+    }
+
+    class ElementKey {
+
+        String key;
+        Element elem;
+
+        public ElementKey(Element elem) {
+            this.elem = elem;
+            this.key = computeKey(elem);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ElementKey) {
+                ElementKey other = (ElementKey)obj;
+                return other.key.equals(key);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return key.hashCode();
+        }
+
+        String computeKey(Element e) {
+            StringBuilder buf = new StringBuilder();
+            while (e != null) {
+                buf.append(e.toString());
+                e = e.getEnclosingElement();
+            }
+            buf.append(jfo.getName());
+            return buf.toString();
+        }
+
+        @Override
+        public String toString() {
+            return "Key{" + key + "}";
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseConditional.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,15 @@
+public class TestCaseConditional {
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=5, bytecodeLength=33),
+        @DARange(varName="oo", bytecodeStart=23, bytecodeLength=15)
+    })
+    void m(String[] args) {
+        Boolean o;
+        Boolean oo = ((o = Boolean.TRUE).booleanValue()) ?
+                o = Boolean.TRUE :
+                Boolean.FALSE;
+        oo.hashCode();
+        o = Boolean.FALSE;
+        o.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseDoLoop.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,15 @@
+public class TestCaseDoLoop {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=3, bytecodeLength=15),
+        @DARange(varName="args", bytecodeStart=0, bytecodeLength=18)
+    })
+    void m(String[] args) {
+        Object o;
+        do {
+            o = "";
+            o.hashCode();
+        } while (args[0] != null);
+        o = "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseFor.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,29 @@
+public class TestCaseFor {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=10, bytecodeLength=11),
+        @DARange(varName="o", bytecodeStart=24, bytecodeLength=1)
+    })
+    void m1(String[] args) {
+        Object o;
+        for (int i = 0; i < 5; i++) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=10, bytecodeLength=11),
+        @DARange(varName="o", bytecodeStart=24, bytecodeLength=1)
+    })
+    void m2(String[] args) {
+        Object o;
+        for (int i = 0; i < 5; i++) {
+            o = "";
+            o.hashCode();
+            continue;
+        }
+        o = "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseForEach.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,15 @@
+public class TestCaseForEach {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=25, bytecodeLength=11),
+        @DARange(varName="o", bytecodeStart=39, bytecodeLength=1)
+    })
+    void m(String[] args) {
+        Object o;
+        for (String s : args) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseIf.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,84 @@
+public class TestCaseIf {
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=9, bytecodeLength=5),
+        @DARange(varName="o", bytecodeStart=17, bytecodeLength=1)
+    })
+    void m0(String[] args) {
+        Object o;
+        if (args[0] != null) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=10, bytecodeLength=5),
+        @DARange(varName="o", bytecodeStart=18, bytecodeLength=1)
+    })
+    void m1() {
+        Object o;
+        int i = 5;
+        if (i == 5) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=10, bytecodeLength=5),
+        @DARange(varName="o", bytecodeStart=18, bytecodeLength=1)
+    })
+    void m2() {
+        Object o;
+        int i = 5;
+        if (!(i == 5)) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=15, bytecodeLength=5),
+        @DARange(varName="o", bytecodeStart=23, bytecodeLength=1)
+    })
+    void m3(String[] args) {
+        Object o;
+        if (args[0] != null && args[1] != null) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=15, bytecodeLength=5),
+        @DARange(varName="o", bytecodeStart=23, bytecodeLength=1)
+    })
+    void m4(String[] args) {
+        Object o;
+        if (args[0] != null || args[1] != null) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="finalLocal", bytecodeStart=11, bytecodeLength=6),
+        @DARange(varName="used", bytecodeStart=13, bytecodeLength=4)
+    })
+    void m5(Object o) {
+        if (o != null) {
+            Object notUsed;
+            Object used;
+            if (o != null) {
+                final Object finalLocal = null;
+                used = null;
+                if (o == null) {}
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseIfElse.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,69 @@
+public class TestCaseIfElse {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=9, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=20, bytecodeLength=9)
+    })
+    void m0(String[] args) {
+        Object o;
+        if (args[0] != null) {
+            o = "then";
+            o.hashCode();
+        } else {
+            o = "else";
+            o.hashCode();
+        }
+        o = "finish";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=10, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=21, bytecodeLength=9)
+    })
+    void m1() {
+        Object o;
+        int i = 5;
+        if (i == 5) {
+            o = "then";
+            o.hashCode();
+        } else {
+            o = "else";
+            o.hashCode();
+        }
+        o = "finish";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=10, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=21, bytecodeLength=9)
+    })
+    void m2() {
+        Object o;
+        int i = 5;
+        if (i != 5) {
+            o = "then";
+            o.hashCode();
+        } else {
+            o = "else";
+            o.hashCode();
+        }
+        o = "finish";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=11, bytecodeLength=3),
+        @DARange(varName="o", bytecodeStart=17, bytecodeLength=2)
+    })
+    Object m3(boolean cond1, boolean cond2) {
+        Object o;
+        if (cond1) {
+            if (cond2) {
+                o = "then";
+            } else {
+                o = "else";
+                return null;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseLocalInInnerBlock.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,20 @@
+public class TestCaseLocalInInnerBlock {
+
+    @DARanges({
+        @DARange(varName="fm", bytecodeStart=23, bytecodeLength=10),
+        @DARange(varName="newWidth", bytecodeStart=2, bytecodeLength=33),
+        @DARange(varName="tc", bytecodeStart=5, bytecodeLength=30)
+    })
+    int m() {
+        int newWidth = 0;
+        String tc = "b";
+        if (tc != null) {
+            String fm;
+            if (tc.trim() != null) {
+            } else if ((fm = "b") != null) {
+                newWidth += fm.length();
+            }
+        }
+        return newWidth;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseSwitch.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,86 @@
+public class TestCaseSwitch {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=31, bytecodeLength=16),
+        @DARange(varName="o", bytecodeStart=50, bytecodeLength=15),
+        @DARange(varName="o", bytecodeStart=68, bytecodeLength=1),
+        @DARange(varName="oo", bytecodeStart=39, bytecodeLength=8),
+        @DARange(varName="uu", bytecodeStart=59, bytecodeLength=6)
+    })
+    void m1(String[] args) {
+        Object o;
+        switch (args.length) {
+            case 0:
+                    o = "0";
+                    o.hashCode();
+                    Object oo = "oo";
+                    oo.hashCode();
+                    break;
+            case 1:
+                    o = "1";
+                    o.hashCode();
+                    Object uu = "uu";
+                    uu.hashCode();
+                    break;
+        }
+        o = "return";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=35, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=46, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=78, bytecodeLength=5),
+        @DARange(varName="o", bytecodeStart=86, bytecodeLength=1),
+        @DARange(varName="oo", bytecodeStart=56, bytecodeLength=16)
+    })
+    void m3(int i) {
+        Object o;
+        switch (i) {
+            case 0:
+                    o = "0";
+                    o.hashCode();
+                    break;
+            case 1:
+                    o = "1";
+                    o.hashCode();
+                    break;
+            case 2:
+                int oo = i;
+                if (oo > 1) {
+                    System.out.println("greater");
+                }
+                break;
+            case 3:
+                int uu = i;
+            default:
+                    o = "default";
+                    o.hashCode();
+        }
+        o = "finish";
+    }
+
+    @DARanges({
+        @DARange(varName="oCache", bytecodeStart=30, bytecodeLength=6),
+        @DARange(varName="cache", bytecodeStart=41, bytecodeLength=3),
+        @DARange(varName="cache", bytecodeStart=54, bytecodeLength=2),
+        @DARange(varName="service", bytecodeStart=39, bytecodeLength=5)
+    })
+    public Object m(int i) {
+        Object cache;
+        switch (i) {
+            case 0:
+                Object oCache = null;
+                if (oCache != null) {
+                    return oCache;
+                }
+            case 1:
+                Object service = null;
+                cache = null;
+                break;
+            default:
+                throw new AssertionError("");
+            }
+        return cache;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseTry.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,55 @@
+public class TestCaseTry {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=3, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=15, bytecodeLength=1)
+    })
+    void m0(String[] args) {
+        Object o;
+        try {
+            o = "";
+            o.hashCode();
+        } catch (RuntimeException e) {}
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=3, bytecodeLength=16),
+        @DARange(varName="o", bytecodeStart=23, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=35, bytecodeLength=11)
+    })
+    void m1() {
+        Object o;
+        try {
+            o = "";
+            o.hashCode();
+        } catch (RuntimeException e) {
+        }
+        finally {
+            o = "finally";
+            o.hashCode();
+        }
+        o = "";
+    }
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=3, bytecodeLength=16),
+        @DARange(varName="o", bytecodeStart=23, bytecodeLength=16),
+        @DARange(varName="o", bytecodeStart=43, bytecodeLength=11)
+    })
+    void m2() {
+        Object o;
+        try {
+            o = "";
+            o.hashCode();
+        } catch (RuntimeException e) {
+            o = "catch";
+            o.hashCode();
+        }
+        finally {
+            o = "finally";
+            o.hashCode();
+        }
+        o = "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/flow/tests/TestCaseWhile.java	Mon Mar 16 11:03:41 2015 -0700
@@ -0,0 +1,15 @@
+public class TestCaseWhile {
+
+    @DARanges({
+        @DARange(varName="o", bytecodeStart=9, bytecodeLength=8),
+        @DARange(varName="o", bytecodeStart=20, bytecodeLength=1)
+    })
+    void m(String[] args) {
+        Object o;
+        while (args[0] != null) {
+            o = "";
+            o.hashCode();
+        }
+        o = "";
+    }
+}