From 4f3a95af2f87756c87fa63d197176cfbb066ecdb Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis Date: Wed, 31 May 2023 09:37:58 +0000 Subject: [PATCH] 8309054: Parsing of erroneous patterns succeeds Reviewed-by: jlahoda --- .../sun/tools/javac/parser/JavacParser.java | 72 +++++++++---------- .../tools/javac/patterns/T8309054.java | 24 +++++++ .../tools/javac/patterns/T8309054.out | 7 ++ 3 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 test/langtools/tools/javac/patterns/T8309054.java create mode 100644 test/langtools/tools/javac/patterns/T8309054.out 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 017dac30e7f..e2e4caeb95b 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 @@ -889,7 +889,11 @@ public class JavacParser implements Parser { } else { //type test pattern: int varPos = token.pos; - JCVariableDecl var = variableDeclaratorRest(varPos, mods, e, identOrUnderscore(), false, null, false, false, true); + Name name = identOrUnderscore(); + if (Feature.UNNAMED_VARIABLES.allowedInSource(source) && name == names.underscore) { + name = names.empty; + } + JCVariableDecl var = toP(F.at(varPos).VarDef(mods, name, e, null)); if (e == null) { var.startPos = pos; if (var.name == names.underscore && !allowVar) { @@ -3618,7 +3622,7 @@ public class JavacParser implements Parser { T vdefs, boolean localDecl) { - JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl, false, false); + JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl, false); vdefs.append(head); while (token.kind == COMMA) { // All but last of multiple declarators subsume a comma @@ -3633,7 +3637,7 @@ public class JavacParser implements Parser { * ConstantDeclarator = Ident ConstantDeclaratorRest */ JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) { - return variableDeclaratorRest(token.pos, mods, type, identOrUnderscore(), reqInit, dc, localDecl, true, false); + return variableDeclaratorRest(token.pos, mods, type, identOrUnderscore(), reqInit, dc, localDecl, true); } /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] @@ -3643,13 +3647,13 @@ public class JavacParser implements Parser { * @param dc The documentation comment for the variable declarations, or null. */ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, - boolean reqInit, Comment dc, boolean localDecl, boolean compound, boolean isTypePattern) { + boolean reqInit, Comment dc, boolean localDecl, boolean compound) { boolean declaredUsingVar = false; - type = bracketsOpt(type); JCExpression init = null; + type = bracketsOpt(type); if (Feature.UNNAMED_VARIABLES.allowedInSource(source) && name == names.underscore) { - if (!localDecl && !isTypePattern) { + if (!localDecl) { log.error(DiagnosticFlag.SYNTAX, pos, Errors.UseOfUnderscoreNotAllowed); } name = names.empty; @@ -3668,38 +3672,32 @@ public class JavacParser implements Parser { syntaxError(token.pos, Errors.Expected(EQ)); } - JCVariableDecl result; - if (!isTypePattern) { - int startPos = Position.NOPOS; - JCTree elemType = TreeInfo.innermostType(type, true); - if (elemType.hasTag(IDENT)) { - Name typeName = ((JCIdent) elemType).name; - if (restrictedTypeNameStartingAtSource(typeName, pos, !compound && localDecl) != null) { - if (typeName != names.var) { - reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedHere(typeName)); - } else if (type.hasTag(TYPEARRAY) && !compound) { - //error - 'var' and arrays - reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedArray(typeName)); - } else { - declaredUsingVar = true; - if (compound) - //error - 'var' in compound local var decl - reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedCompound(typeName)); - startPos = TreeInfo.getStartPos(mods); - if (startPos == Position.NOPOS) - startPos = TreeInfo.getStartPos(type); - //implicit type - type = null; - } + int startPos = Position.NOPOS; + JCTree elemType = TreeInfo.innermostType(type, true); + if (elemType.hasTag(IDENT)) { + Name typeName = ((JCIdent) elemType).name; + if (restrictedTypeNameStartingAtSource(typeName, pos, !compound && localDecl) != null) { + if (typeName != names.var) { + reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedHere(typeName)); + } else if (type.hasTag(TYPEARRAY) && !compound) { + //error - 'var' and arrays + reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedArray(typeName)); + } else { + declaredUsingVar = true; + if (compound) + //error - 'var' in compound local var decl + reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedCompound(typeName)); + startPos = TreeInfo.getStartPos(mods); + if (startPos == Position.NOPOS) + startPos = TreeInfo.getStartPos(type); + //implicit type + type = null; } } - result = toP(F.at(pos).VarDef(mods, name, type, init, declaredUsingVar)); - attach(result, dc); - result.startPos = startPos; - } else { - result = toP(F.at(pos).VarDef(mods, name, type, null)); } - + JCVariableDecl result = toP(F.at(pos).VarDef(mods, name, type, init, declaredUsingVar)); + attach(result, dc); + result.startPos = startPos; return result; } @@ -3843,12 +3841,12 @@ public class JavacParser implements Parser { if (token.kind == FINAL || token.kind == MONKEYS_AT) { JCModifiers mods = optFinal(0); JCExpression t = parseType(true); - return variableDeclaratorRest(token.pos, mods, t, identOrUnderscore(), true, null, true, false, false); + return variableDeclaratorRest(token.pos, mods, t, identOrUnderscore(), true, null, true, false); } JCExpression t = term(EXPR | TYPE); if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) { JCModifiers mods = F.Modifiers(0); - return variableDeclaratorRest(token.pos, mods, t, identOrUnderscore(), true, null, true, false, false); + return variableDeclaratorRest(token.pos, mods, t, identOrUnderscore(), true, null, true, false); } else { checkSourceLevel(Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES); if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) { diff --git a/test/langtools/tools/javac/patterns/T8309054.java b/test/langtools/tools/javac/patterns/T8309054.java new file mode 100644 index 00000000000..27e9cbe0c1b --- /dev/null +++ b/test/langtools/tools/javac/patterns/T8309054.java @@ -0,0 +1,24 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8309054 + * @summary Parsing of erroneous patterns succeeds + * @enablePreview + * @compile/fail/ref=T8309054.out -XDrawDiagnostics --should-stop=at=FLOW T8309054.java + */ + +public class T8309054 { + public void test(Object obj) { + boolean t1 = switch (obj) { + case Long a[] -> true; + default -> false; + }; + boolean t2 = switch (obj) { + case Double a[][][][] -> true; + default -> false; + }; + if (obj instanceof Float a[][]) { + } + if (obj instanceof Integer a = Integer.valueOf(0)) { + } + } +} \ No newline at end of file diff --git a/test/langtools/tools/javac/patterns/T8309054.out b/test/langtools/tools/javac/patterns/T8309054.out new file mode 100644 index 00000000000..4397d51ec0b --- /dev/null +++ b/test/langtools/tools/javac/patterns/T8309054.out @@ -0,0 +1,7 @@ +T8309054.java:12:24: compiler.err.expected2: :, -> +T8309054.java:16:26: compiler.err.expected2: :, -> +T8309054.java:19:35: compiler.err.expected: ')' +T8309054.java:13:13: compiler.err.switch.mixing.case.types +T8309054.java:17:13: compiler.err.switch.mixing.case.types +T8309054.java:21:17: compiler.err.unexpected.type: kindname.variable, kindname.value +6 errors \ No newline at end of file