diff --git a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/JavaSourceBuilder.java b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/JavaSourceBuilder.java index 70e22fc2770..2d3936a26cd 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/JavaSourceBuilder.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/JavaSourceBuilder.java @@ -229,9 +229,7 @@ protected void emitImportSection() { append("import java.lang.invoke.MethodHandle;\n"); append("import java.lang.invoke.VarHandle;\n"); append("import java.nio.ByteOrder;\n"); - append("import java.util.Objects;\n"); append("import jdk.incubator.foreign.*;\n"); - append("import jdk.incubator.foreign.MemoryLayout.PathElement;\n"); append("import static "); append(OutputFactory.C_LANG_CONSTANTS_HOLDER); append(".*;\n"); diff --git a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/Utils.java b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/Utils.java index 3412dcf2b4f..f2c0084f7bf 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/Utils.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/Utils.java @@ -95,7 +95,7 @@ static String javaSafeIdentifier(String name, boolean checkAllChars) { // C identifiers. But we may have a java keyword used as a C identifier. assert SourceVersion.isIdentifier(name); - return SourceVersion.isKeyword(name) || isRestrictedTypeName(name) ? (name + "_") : name; + return SourceVersion.isKeyword(name) || isRestrictedTypeName(name) || isJavaTypeName(name)? (name + "_") : name; } } @@ -107,6 +107,19 @@ private static boolean isRestrictedTypeName(String name) { }; } + private static boolean isJavaTypeName(String name) { + // Java types that are used unqualified in the generated code + return switch (name) { + case "String", "MethodHandle", + "VarHandle", "ByteOrder", + "FunctionDescriptor", "LibraryLookup", + "MemoryAddress", "MemoryLayout", + "MemorySegment", "ValueLayout", + "RuntimeHelper" -> true; + default -> false; + }; + } + static void validSimpleIdentifier(String name) { int length = name.length(); if (length == 0) { diff --git a/test/jdk/tools/jextract/Test8262825.java b/test/jdk/tools/jextract/Test8262825.java new file mode 100644 index 00000000000..75491c204d4 --- /dev/null +++ b/test/jdk/tools/jextract/Test8262825.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, 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 org.testng.annotations.Test; +import java.nio.file.Path; +import static org.testng.Assert.assertNotNull; + +/* + * @test + * @modules jdk.incubator.jextract + * @library /test/lib + * @build JextractToolRunner + * @bug 8262825 + * @summary jextract crashes when Java type names like String are used as identifiers in C heade + * @run testng/othervm -Dforeign.restricted=permit Test8262825 + */ +public class Test8262825 extends JextractToolRunner { + @Test + public void test() { + Path output = getOutputFilePath("8262825gen"); + Path outputH = getInputFilePath("test8262825.h"); + run("-d", output.toString(), outputH.toString()).checkSuccess(); + try(Loader loader = classLoader(output)) { + Class<?> cls = loader.loadClass("test8262825_h"); + assertNotNull(cls); + + assertNotNull(findField(cls, "MemoryLayout_")); + assertNotNull(findField(cls, "ValueLayout_")); + + assertNotNull(loader.loadClass("test8262825_h$RuntimeHelper_")); + assertNotNull(loader.loadClass("test8262825_h$String_")); + assertNotNull(loader.loadClass("test8262825_h$MemoryAddress_")); + assertNotNull(loader.loadClass("test8262825_h$MemorySegment_")); + } finally { + deleteDir(output); + } + } +} diff --git a/test/jdk/tools/jextract/test8262825.h b/test/jdk/tools/jextract/test8262825.h new file mode 100644 index 00000000000..b9a64836020 --- /dev/null +++ b/test/jdk/tools/jextract/test8262825.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, 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. + */ + +struct String { + int x, y; +}; + +struct RuntimeHelper { + int x; +}; + +union MemorySegment { + int x; float f; +}; + +union MemoryAddress { + long l; double d; +}; + +typedef long MemoryLayout; +typedef double ValueLayout;