1 /* 2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @test 28 * @bug 8022186 29 * @summary javac generates dead code if a try with an empty body has a finalizer 30 * @modules jdk.compiler/com.sun.tools.classfile 31 * jdk.compiler/com.sun.tools.javac.util 32 */ 33 34 import com.sun.tools.classfile.Attribute; 35 import com.sun.tools.classfile.ClassFile; 36 import com.sun.tools.classfile.Code_attribute; 37 import com.sun.tools.classfile.ConstantPool; 38 import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info; 39 import com.sun.tools.classfile.ConstantPool.CPInfo; 40 import com.sun.tools.classfile.ConstantPool.InvalidIndex; 41 import com.sun.tools.classfile.Instruction; 42 import com.sun.tools.classfile.Instruction.KindVisitor; 43 import com.sun.tools.classfile.Instruction.TypeKind; 44 import com.sun.tools.classfile.Method; 45 import com.sun.tools.javac.util.Assert; 46 import java.io.BufferedInputStream; 47 import java.nio.file.Files; 48 import java.nio.file.Path; 49 import java.nio.file.Paths; 50 51 public class DeadCodeGeneratedForEmptyTryTest { 52 53 public static void main(String[] args) throws Exception { 54 new DeadCodeGeneratedForEmptyTryTest().run(); 55 } 56 57 void run() throws Exception { 58 checkClassFile(Paths.get(System.getProperty("test.classes"), 59 this.getClass().getName() + "$Test.class")); 60 } 61 62 int utf8Index; 63 int numberOfRefToStr = 0; 64 ConstantPool constantPool; 65 66 void checkClassFile(final Path path) throws Exception { 67 ClassFile classFile = ClassFile.read( 68 new BufferedInputStream(Files.newInputStream(path))); 69 constantPool = classFile.constant_pool; 70 utf8Index = constantPool.getUTF8Index("STR_TO_LOOK_FOR"); 71 for (Method method: classFile.methods) { 72 if (method.getName(constantPool).equals("methodToLookFor")) { 73 Code_attribute codeAtt = (Code_attribute)method.attributes.get(Attribute.Code); 74 for (Instruction inst: codeAtt.getInstructions()) { 75 inst.accept(codeVisitor, null); 76 } 77 } 78 } 79 Assert.check(numberOfRefToStr == 1, 80 "There should only be one reference to a CONSTANT_String_info structure in the generated code"); 81 } 82 83 CodeVisitor codeVisitor = new CodeVisitor(); 84 85 class CodeVisitor implements KindVisitor<Void, Void> { 86 87 void checkIndirectRefToString(int cp_index) { 88 try { 89 CPInfo cInfo = constantPool.get(cp_index); 90 if (cInfo instanceof CONSTANT_String_info) { 91 CONSTANT_String_info strInfo = (CONSTANT_String_info)cInfo; 92 if (strInfo.string_index == utf8Index) { 93 numberOfRefToStr++; 94 } 95 } 96 } catch (InvalidIndex ex) { 97 throw new AssertionError("invalid constant pool index at " + cp_index); 98 } 99 } 100 101 @Override 102 public Void visitNoOperands(Instruction instr, Void p) { 103 return null; 104 } 105 106 @Override 107 public Void visitArrayType(Instruction instr, TypeKind kind, Void p) { 108 return null; 109 } 110 111 @Override 112 public Void visitBranch(Instruction instr, int offset, Void p) { 113 return null; 114 } 115 116 @Override 117 public Void visitConstantPoolRef(Instruction instr, int index, Void p) { 118 checkIndirectRefToString(index); 119 return null; 120 } 121 122 @Override 123 public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) { 124 checkIndirectRefToString(index); 125 return null; 126 } 127 128 @Override 129 public Void visitLocal(Instruction instr, int index, Void p) { 130 return null; 131 } 132 133 @Override 134 public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) { 135 return null; 136 } 137 138 @Override 139 public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Void p) { 140 return null; 141 } 142 143 @Override 144 public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Void p) { 145 return null; 146 } 147 148 @Override 149 public Void visitValue(Instruction instr, int value, Void p) { 150 return null; 151 } 152 153 @Override 154 public Void visitUnknown(Instruction instr, Void p) { 155 return null; 156 } 157 158 } 159 160 public class Test { 161 void methodToLookFor() { 162 try { 163 } finally { 164 System.out.println("STR_TO_LOOK_FOR"); 165 } 166 } 167 } 168 }