From 1831b6c29617b26463b5e5acb6f823912eeaa1fe Mon Sep 17 00:00:00 2001 From: Angelos Bimpoudis Date: Thu, 23 Jan 2025 15:36:43 +0100 Subject: [PATCH] Fix instanceof statement reporting --- .../sun/tools/javac/parser/JavacParser.java | 13 +++++++- .../tools/javac/resources/compiler.properties | 3 ++ .../InstanceofStatementPatternOnly.java | 33 +++++++++++++++++++ .../InstanceOfStatementErrors.java | 7 +++- .../InstanceOfStatementErrors.out | 3 +- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 test/langtools/tools/javac/diags/examples/InstanceofStatementPatternOnly.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index de0f256f404..3febf828a67 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -3036,8 +3036,19 @@ List blockStatement() { } else { if (t.getTag() == TYPETEST && allowPatternDeclarations) { t = term2Rest(t, TreeInfo.orPrec); + accept(SEMI); - return List.of(toP(F.at(pos).TypeTestStatement(((JCInstanceOf) t).expr, ((JCInstanceOf)t ).getPattern()))); + + JCExpression expr = ((JCInstanceOf) t).expr; + JCPattern pattern = ((JCInstanceOf) t).getPattern(); + + if (pattern == null) { + log.error(DiagnosticFlag.SYNTAX, expr, Errors.InstanceofStatementPatternOnly); + return List.of(toP(F.at(pos).Exec(checkExprStat(expr)))); + } + + return List.of(toP(F.at(pos).TypeTestStatement(expr, pattern))); + } else { // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon t = checkExprStat(t); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 749203eb5a9..e55fd1c3ead 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1548,6 +1548,9 @@ compiler.misc.varargs.trustme.on.reifiable.varargs=\ compiler.err.instanceof.reifiable.not.safe=\ {0} cannot be safely cast to {1} +compiler.err.instanceof.statement.pattern.only=\ + instanceof as a statement should act as a pattern matching operator and not as a type comparison operator + # 0: symbol compiler.misc.varargs.trustme.on.non.varargs.meth=\ Method {0} is not a varargs method. diff --git a/test/langtools/tools/javac/diags/examples/InstanceofStatementPatternOnly.java b/test/langtools/tools/javac/diags/examples/InstanceofStatementPatternOnly.java new file mode 100644 index 00000000000..c7ba196c8cf --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/InstanceofStatementPatternOnly.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, 2020, 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. + */ + +// key: compiler.err.instanceof.statement.pattern.only +// options: --enable-preview -source ${jdk.version} -Xlint:preview + +import java.util.List; + +class InstanceofStatementPatternOnly { + static void patterns_only(Object point) { + point instanceof int; + } +} diff --git a/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.java b/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.java index e31976f82c3..b2f5e92932c 100644 --- a/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.java +++ b/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.java @@ -9,10 +9,15 @@ public class InstanceOfStatementErrors { static void exhaustivity_error1(Object point) { - point instanceof Point(var x, var y); + point instanceof Point(var x, var y); // error } sealed interface IPoint permits Point {} record Point(Integer x, Integer y) implements IPoint { } record OPoint(Object x, Object y) { } + + static void patterns_only(Object point) { + point instanceof int; // error + } + } \ No newline at end of file diff --git a/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.out b/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.out index 15d9970521c..62ab76ada19 100644 --- a/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.out +++ b/test/langtools/tools/javac/patterns/declarations/InstanceOfStatementErrors.out @@ -1,2 +1,3 @@ +InstanceOfStatementErrors.java:20:9: compiler.err.instanceof.statement.pattern.only InstanceOfStatementErrors.java:12:9: compiler.err.not.exhaustive.statement -1 error +2 errors