1 /*
 2  * Copyright (c) 2022, 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 8280942
27  * @summary Preload attribute should mention primitive classes when reference projection is used in descriptors
28  * @modules jdk.jdeps/com.sun.tools.classfile
29  * @run main PreloadAttributeTest
30  */
31 
32 import com.sun.tools.classfile.*;
33 import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
34 
35 public class PreloadAttributeTest {
36 
37     public primitive class P1 {}
38     public primitive class P2 {}
39     public primitive class P3 {}
40     public primitive class P4 {}
41     public primitive class P5 {}
42     public primitive class P6 {}
43     public primitive class P7 {}
44     public primitive class P8 {}
45 
46     // We expect NO Preload Entries for ANY of P1 .. P4
47     P1 p1;
48     P2 foo(P3 p3) {
49         P4 p4;
50         return new P2();
51     }
52 
53     // We expect Preload Entries for ALL of P5 .. P8
54     P5.ref p5;
55     P6.ref foo(P7.ref p7) {
56         P8.ref p8;
57         return null;
58     }
59 
60     public static void main(String[] args) throws Exception {
61         ClassFile cls = ClassFile.read(PreloadAttributeTest.class.getResourceAsStream("PreloadAttributeTest.class"));
62 
63         if (cls == null) {
64             throw new AssertionError("Could not locate the class files");
65         }
66 
67         /* Check emission of Preload attribute */
68         Preload_attribute preloads = (Preload_attribute) cls.attributes.get(Attribute.Preload);
69         if (preloads == null) {
70             throw new AssertionError("Missing Preload attribute!");
71         }
72         if (preloads.number_of_classes != 4) {
73             throw new AssertionError("Incorrect number of Preload classes");
74         }
75 
76         int mask = 0xF0;
77         for (int i = 0; i < preloads.number_of_classes; i++) {
78             CONSTANT_Class_info clsInfo = cls.constant_pool.getClassInfo(
79                                   preloads.value_class_info_index[i]);
80             switch (clsInfo.getName()) {
81                 case "PreloadAttributeTest$P5":
82                     mask &= ~16; break;
83                 case "PreloadAttributeTest$P6":
84                     mask &= ~32; break;
85                 case "PreloadAttributeTest$P7":
86                     mask &= ~64; break;
87                 case "PreloadAttributeTest$P8" :
88                     mask &= ~128; break;
89                 default:
90                     throw new AssertionError("Unexpected Preload class entry: " + clsInfo.getName());
91             }
92         }
93         if (mask != 0) {
94           throw new AssertionError("Some Preload class entries are missing!");
95         }
96     }
97 }