< prev index next >

test/jdk/java/io/Serializable/records/BadCanonicalCtrTest.java

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2019, 2026, 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.

@@ -38,20 +38,18 @@
  import java.io.ObjectOutputStream;
  import java.io.ObjectStreamClass;
  import java.lang.classfile.ClassTransform;
  import java.lang.classfile.ClassFile;
  import java.lang.classfile.MethodModel;
+ import java.lang.classfile.TypeKind;
  import java.lang.constant.MethodTypeDesc;
  
  import jdk.test.lib.compiler.InMemoryJavaCompiler;
  import jdk.test.lib.ByteCodeLoader;
  import static java.lang.System.out;
- import static java.lang.classfile.ClassFile.ACC_PUBLIC;
- import static java.lang.constant.ConstantDescs.CD_Object;
- import static java.lang.constant.ConstantDescs.CD_void;
- import static java.lang.constant.ConstantDescs.INIT_NAME;
- import static java.lang.constant.ConstantDescs.MTD_void;
+ import static java.lang.classfile.ClassFile.*;
+ import static java.lang.constant.ConstantDescs.*;
  
  import org.junit.jupiter.api.Assertions;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  import org.junit.jupiter.api.BeforeAll;
  import org.junit.jupiter.api.TestInstance;

@@ -218,14 +216,33 @@
       * Modifies the descriptor of the constructor from the given class bytes.
       * Assumes just a single, canonical, constructor.
       */
      static byte[] modifyConstructor(byte[] classBytes) {
          var cf = ClassFile.of();
+         var classModel = cf.parse(classBytes);
          return cf.transformClass(cf.parse(classBytes), ClassTransform.dropping(ce ->
                          ce instanceof MethodModel mm && mm.methodName().equalsString(INIT_NAME))
                  .andThen(ClassTransform.endHandler(clb -> clb.withMethodBody(INIT_NAME,
                          MethodTypeDesc.of(CD_void, CD_Object), ACC_PUBLIC, cob -> {
+                             // Initialize strict fields, if any
+                             for (var field : classModel.fields()) {
+                                 if ((field.flags().flagsMask() & (ACC_STRICT_INIT | ACC_STATIC)) != ACC_STRICT_INIT) {
+                                     continue;
+                                 }
+                                 var fieldType = field.fieldTypeSymbol();
+                                 cob.aload(0);
+                                 switch (TypeKind.from(fieldType).asLoadable()) {
+                                     case INT -> cob.iconst_0();
+                                     case LONG -> cob.lconst_0();
+                                     case FLOAT -> cob.fconst_0();
+                                     case DOUBLE -> cob.dconst_0();
+                                     case REFERENCE -> cob.aconst_null();
+                                     default -> throw new IllegalArgumentException(fieldType.descriptorString());
+                                 }
+                                 var cp = cob.constantPool();
+                                 cob.putfield(cp.fieldRefEntry(classModel.thisClass(), cp.nameAndTypeEntry(field.fieldName(), field.fieldType())));
+                             }
                              cob.aload(0);
                              cob.invokespecial(Record.class.describeConstable().orElseThrow(),
                                      INIT_NAME, MTD_void);
                              cob.return_();
                          }))));
< prev index next >