Skip to content

Commit

Permalink
8027682: javac wrongly accepts semicolons in package and import decls
Browse files Browse the repository at this point in the history
Reviewed-by: vromero
  • Loading branch information
archiecobbs authored and Vicente Romero committed Mar 23, 2023
1 parent c00d088 commit 4b8f7db
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3839,16 +3839,32 @@ public JCTree.JCCompilationUnit parseCompilationUnit() {
defs.append(pd);
}

boolean checkForImports = true;
boolean firstTypeDecl = true;
boolean firstTypeDecl = true; // have we see a class, enum, or interface declaration yet?
while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
skip(checkForImports, false, false, false);
skip(firstTypeDecl, false, false, false);
if (token.kind == EOF)
break;
}
if (checkForImports && mods == null && token.kind == IMPORT) {
// JLS 7.3 doesn't allow extra semicolons after package or import declarations,
// but here we try to provide a more helpful error message if we encounter any.
// Do that by slurping in as many semicolons as possible, and then seeing what
// comes after before deciding how best to handle them.
ListBuffer<JCTree> semiList = new ListBuffer<>();
while (firstTypeDecl && mods == null && token.kind == SEMI) {
semiList.append(toP(F.at(token.pos).Skip()));
nextToken();
if (token.kind == EOF)
break;
}
if (firstTypeDecl && mods == null && token.kind == IMPORT) {
if (!semiList.isEmpty()) {
if (source.compareTo(Source.JDK21) >= 0)
reportSyntaxError(semiList.first().pos, Errors.ExtraneousSemicolon);
else
log.warning(semiList.first().pos, Warnings.ExtraneousSemicolon);
}
seenImport = true;
defs.append(importDeclaration());
} else {
Expand All @@ -3860,6 +3876,12 @@ public JCTree.JCCompilationUnit parseCompilationUnit() {
if (mods != null || token.kind != SEMI)
mods = modifiersOpt(mods);
if (firstTypeDecl && token.kind == IDENTIFIER) {
if (!semiList.isEmpty()) {
if (source.compareTo(Source.JDK21) >= 0)
reportSyntaxError(semiList.first().pos, Errors.ExtraneousSemicolon);
else
log.warning(semiList.first().pos, Warnings.ExtraneousSemicolon);
}
ModuleKind kind = ModuleKind.STRONG;
if (token.name() == names.open) {
kind = ModuleKind.OPEN;
Expand All @@ -3876,12 +3898,11 @@ public JCTree.JCCompilationUnit parseCompilationUnit() {
reportSyntaxError(token.pos, Errors.ExpectedModule);
}
}
defs.appendList(semiList.toList());
JCTree def = typeDeclaration(mods, docComment);
if (def instanceof JCExpressionStatement statement)
def = statement.expr;
defs.append(def);
if (def instanceof JCClassDecl)
checkForImports = false;
mods = null;
firstTypeDecl = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2358,6 +2358,12 @@ compiler.err.enum.constant.expected=\
compiler.err.enum.constant.not.expected=\
enum constant not expected here

compiler.err.extraneous.semicolon=\
extraneous semicolon

compiler.warn.extraneous.semicolon=\
extraneous semicolon

## The following are related in form, but do not easily fit the above paradigm.
compiler.err.expected.module.or.open=\
''module'' or ''open'' expected
Expand Down
2 changes: 1 addition & 1 deletion test/jdk/com/sun/jndi/dns/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

import com.sun.jndi.dns.ResourceRecord;
import javax.naming.CommunicationException;
import javax.naming.InvalidNameException;;
import javax.naming.InvalidNameException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.security.AccessControlException;;
import java.security.Permission;;
import java.security.AccessControlException;
import java.security.Permission;

import static jdk.test.lib.Asserts.*;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import javax.management.*;
import javax.management.openmbean.CompositeData;
import java.lang.management.*;
import static java.lang.management.MemoryNotificationInfo.*;;
import static java.lang.management.MemoryNotificationInfo.*;
import static java.lang.management.ManagementFactory.*;

import jdk.test.whitebox.code.Compiler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeoutException;;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import static java.nio.file.StandardOpenOption.*;
Expand Down
2 changes: 1 addition & 1 deletion test/jdk/jdk/jfr/tool/ExecuteHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.Utils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;;
import jdk.test.lib.process.ProcessTools;

final class ExecuteHelper {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AnnotatedImport.java:10:13: compiler.err.expected: token.identifier
AnnotatedImport.java:10:16: compiler.err.expected4: class, interface, enum, record
AnnotatedImport.java:11:7: compiler.err.expected: token.identifier
AnnotatedImport.java:11:1: compiler.err.expected4: class, interface, enum, record
AnnotatedImport.java:11:11: compiler.err.expected4: class, interface, enum, record
AnnotatedImport.java:12:18: compiler.err.expected: token.identifier
AnnotatedImport.java:12:1: compiler.err.expected4: class, interface, enum, record
AnnotatedImport.java:12:21: compiler.err.expected4: class, interface, enum, record
6 errors
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
AnnotatedPackage1.java:9:14: compiler.err.expected: token.identifier
AnnotatedPackage1.java:9:17: compiler.err.expected4: class, interface, enum, record
2 errors
AnnotatedPackage1.java:11:1: compiler.err.expected4: class, interface, enum, record
3 errors
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
AnnotatedPackage2.java:9:8: compiler.err.expected: token.identifier
AnnotatedPackage2.java:9:12: compiler.err.expected4: class, interface, enum, record
2 errors
AnnotatedPackage2.java:11:1: compiler.err.expected4: class, interface, enum, record
3 errors
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023, 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.extraneous.semicolon

import java.util.Map;; // NOTE: extra semicolon
import java.util.Set;

class ExtraImportSemicolonError {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2023, 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.warn.extraneous.semicolon
// options: --release 20

import java.util.Map;; // NOTE: extra semicolon
import java.util.Set;

class ExtraImportSemicolonWarning {
}
13 changes: 13 additions & 0 deletions test/langtools/tools/javac/parser/ExtraImportSemicolon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* @test /nodynamiccopyright/
* @bug 5059679
* @summary Verify proper error reporting of extra semicolon before import statement
* @compile/fail/ref=ExtraImportSemicolon.out1 -XDrawDiagnostics ExtraImportSemicolon.java
* @compile/ref=ExtraImportSemicolon.out2 --release 20 -XDrawDiagnostics ExtraImportSemicolon.java
*/

import java.util.Map;; // NOTE: extra semicolon
import java.util.Set;

class ExtraImportSemicolon {
}
2 changes: 2 additions & 0 deletions test/langtools/tools/javac/parser/ExtraImportSemicolon.out1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ExtraImportSemicolon.java:9:22: compiler.err.extraneous.semicolon
1 error
2 changes: 2 additions & 0 deletions test/langtools/tools/javac/parser/ExtraImportSemicolon.out2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ExtraImportSemicolon.java:9:22: compiler.warn.extraneous.semicolon
1 warning
60 changes: 0 additions & 60 deletions test/langtools/tools/javac/tree/T6963934.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

package q;

import jdk.internal.perf.PerfCounter;;
import jdk.internal.perf.PerfCounter;

public class Counter {
public static void create(String name) {
Expand Down
2 changes: 1 addition & 1 deletion test/langtools/tools/lib/types/TypeHarness.java
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ class JavaSource extends SimpleJavaFileObject {

String id;
String type;
String template = "#Package;\n" +
String template = "#Package\n" +
"#Imports\n" +
"class G#Id#TypeVars {\n" +
" #FieldType var;" +
Expand Down

1 comment on commit 4b8f7db

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.