NonDirectSuper.java revision 2942:08092deced3f
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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8027789
27 * @summary check that the direct superclass is used as the site when calling
28 *          a superclass' method
29 * @modules jdk.jdeps/com.sun.tools.classfile
30 * @compile Base.java NonDirectSuper.java
31 * @run main test.NonDirectSuper
32 */
33
34package test;
35
36import java.io.File;
37
38import com.sun.tools.classfile.Attribute;
39import com.sun.tools.classfile.ClassFile;
40import com.sun.tools.classfile.Code_attribute;
41import com.sun.tools.classfile.ConstantPool.CPRefInfo;
42import com.sun.tools.classfile.Instruction;
43import com.sun.tools.classfile.Method;
44import com.sun.tools.classfile.Opcode;
45
46public class NonDirectSuper {
47    public static void main(String... args) {
48        new NonDirectSuper().run();
49    }
50
51    void run() {
52        String workDir = System.getProperty("test.classes");
53        File testPackage = new File(workDir, "test");
54
55        for (File clazz : testPackage.listFiles()) {
56            if ("NonDirectSuper.class".equals(clazz.getName())) continue;
57            verifyInvokeSpecialRefToObject(clazz);
58        }
59    }
60
61    void verifyInvokeSpecialRefToObject(File clazz) {
62        try {
63            final ClassFile cf = ClassFile.read(clazz);
64            for (Method m : cf.methods) {
65                Code_attribute codeAttr = (Code_attribute)m.attributes.get(Attribute.Code);
66                for (Instruction instr : codeAttr.getInstructions()) {
67                    if (instr.getOpcode() == Opcode.INVOKESPECIAL ||
68                        instr.getOpcode() == Opcode.INVOKEVIRTUAL) {
69                        int pc_index = instr.getShort(1);
70                        CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index);
71                        String className = ref.getClassName();
72                        String methodName = ref.getNameAndTypeInfo().getName();
73                        if (methodName.equals("toString")) {
74                            if (!className.equals("java/lang/Object"))
75                                throw new IllegalStateException("Must directly refer to j.l.Object");
76                        } else if (methodName.startsWith("refTo")) {
77                            String expectedClass = methodName.substring("refTo".length());
78                            if (!className.replace("/", "").equals(expectedClass)) {
79                                throw new IllegalStateException("Unexpected reference to: " +
80                                        className + ", should be " + expectedClass);
81                            }
82                        }
83                    }
84                    if (instr.getOpcode() == Opcode.GETFIELD ||
85                        instr.getOpcode() == Opcode.PUTFIELD) {
86                        int pc_index = instr.getShort(1);
87                        CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index);
88                        String className = ref.getClassName();
89                        String fieldName = ref.getNameAndTypeInfo().getName();
90                        if (fieldName.startsWith("refTo")) {
91                            String expectedClass = fieldName.substring("refTo".length());
92                            if (!className.replace("/", "").equals(expectedClass)) {
93                                throw new IllegalStateException("Unexpected reference to: " +
94                                        className + ", should be " + expectedClass);
95                            }
96                        }
97                    }
98                }
99            }
100        } catch (Exception e) {
101            e.printStackTrace();
102            throw new Error("error reading " + clazz +": " + e);
103        }
104    }
105}
106
107class OtherPackageTest extends base.Base {
108    void run() {
109        new Runnable() {
110            public void run() {
111                OtherPackageTest.super.refTobaseBase();
112                OtherPackageTest.super.refTobaseBase = OtherPackageTest.super.refTobaseBase + 1;
113                OtherPackageTest.super.toString();
114                refTotestOtherPackageTest();
115                refTotestOtherPackageTest = refTotestOtherPackageTest + 1;
116                OtherPackageTest.this.refTotestOtherPackageTest();
117                OtherPackageTest.this.refTotestOtherPackageTest =
118                        OtherPackageTest.this.refTotestOtherPackageTest + 1;
119            }
120        }.run();
121        super.refTobaseBase();
122        super.refTobaseBase = super.refTobaseBase + 1;
123        super.toString();
124        OtherPackageTest.super.refTobaseBase();
125        OtherPackageTest.super.refTobaseBase = OtherPackageTest.super.refTobaseBase + 1;
126        OtherPackageTest.super.toString();
127        refTotestOtherPackageTest();
128        refTotestOtherPackageTest = refTotestOtherPackageTest + 1;
129    }
130
131    static class InnerBase {
132        private void refTotestOtherPackageTest$InnerBase() { }
133    }
134    static class InnerTest extends InnerBase {
135        void run() {
136            new Runnable() {
137                public void run() {
138                    InnerTest.super.refTotestOtherPackageTest$InnerBase();
139                }
140            }.run();
141            super.refTotestOtherPackageTest$InnerBase();
142            InnerTest.super.refTotestOtherPackageTest$InnerBase();
143        }
144    }
145}
146
147class CurPackagePrivateBase {
148    void refTotestCurPackagePrivateExt() { }
149    void refTotestCurPackagePrivateTest() { }
150    int refTotestCurPackagePrivateExt;
151    int refTotestCurPackagePrivateTest;
152}
153
154class CurPackagePrivateExt extends CurPackagePrivateBase {
155}
156
157class CurPackagePrivateTest extends CurPackagePrivateExt {
158    void run() {
159        new Runnable() {
160            public void run() {
161                CurPackagePrivateTest.super.refTotestCurPackagePrivateExt();
162                CurPackagePrivateTest.super.refTotestCurPackagePrivateExt =
163                        CurPackagePrivateTest.super.refTotestCurPackagePrivateExt + 1;
164                CurPackagePrivateTest.this.refTotestCurPackagePrivateTest();
165                CurPackagePrivateTest.this.refTotestCurPackagePrivateTest =
166                        CurPackagePrivateTest.this.refTotestCurPackagePrivateTest + 1;
167                refTotestCurPackagePrivateTest();
168                refTotestCurPackagePrivateTest = refTotestCurPackagePrivateTest + 1;
169            }
170        }.run();
171        super.refTotestCurPackagePrivateExt();
172        super.refTotestCurPackagePrivateExt = super.refTotestCurPackagePrivateExt + 1;
173        CurPackagePrivateTest.super.refTotestCurPackagePrivateExt();
174        CurPackagePrivateTest.super.refTotestCurPackagePrivateExt =
175                CurPackagePrivateTest.super.refTotestCurPackagePrivateExt + 1;
176        refTotestCurPackagePrivateTest();
177        refTotestCurPackagePrivateTest = refTotestCurPackagePrivateTest + 1;
178    }
179}
180