Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
1.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Mon Jun 26 10:38:22 2017 +0200
1.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Mon Jul 31 11:07:41 2017 +0200
1.3 @@ -355,6 +355,8 @@
1.4 JavaFileObject classfile = c.classfile;
1.5 if (classfile != null) {
1.6 JavaFileObject previousClassFile = currentClassFile;
1.7 + Symbol prevOwner = c.owner;
1.8 + Name prevName = c.fullname;
1.9 try {
1.10 if (reader.filling) {
1.11 Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
1.12 @@ -377,6 +379,21 @@
1.13 + classfile.toUri());
1.14 }
1.15 }
1.16 + } catch (BadClassFile cf) {
1.17 + //the symbol may be partially initialized, purge it:
1.18 + c.owner = prevOwner;
1.19 + c.members_field.getSymbols(sym -> sym.kind == TYP).forEach(sym -> {
1.20 + ClassSymbol csym = (ClassSymbol) sym;
1.21 + csym.owner = sym.packge();
1.22 + csym.owner.members().enter(sym);
1.23 + csym.fullname = sym.flatName();
1.24 + csym.name = Convert.shortName(sym.flatName());
1.25 + csym.reset();
1.26 + });
1.27 + c.fullname = prevName;
1.28 + c.name = Convert.shortName(prevName);
1.29 + c.reset();
1.30 + throw cf;
1.31 } finally {
1.32 currentClassFile = previousClassFile;
1.33 }
2.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java Mon Jun 26 10:38:22 2017 +0200
2.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java Mon Jul 31 11:07:41 2017 +0200
2.3 @@ -31,7 +31,6 @@
2.4 import java.util.Map;
2.5 import java.util.NoSuchElementException;
2.6 import java.util.Set;
2.7 -import java.util.function.Function;
2.8
2.9 import javax.tools.JavaFileManager;
2.10 import javax.tools.JavaFileManager.Location;
2.11 @@ -58,6 +57,7 @@
2.12 import com.sun.tools.javac.util.Names;
2.13
2.14 import static com.sun.tools.javac.code.Kinds.Kind.*;
2.15 +import com.sun.tools.javac.comp.Check;
2.16
2.17 /**
2.18 * This class provides operations to locate module definitions
2.19 @@ -82,6 +82,7 @@
2.20 private final Names names;
2.21
2.22 private final ClassFinder classFinder;
2.23 + private final Check chk;
2.24
2.25 /** Access to files
2.26 */
2.27 @@ -109,6 +110,7 @@
2.28 fileManager = context.get(JavaFileManager.class);
2.29 log = Log.instance(context);
2.30 classFinder = ClassFinder.instance(context);
2.31 + chk = Check.instance(context);
2.32
2.33 diags = JCDiagnostic.Factory.instance(context);
2.34 }
2.35 @@ -203,7 +205,13 @@
2.36 if (fo == null) {
2.37 msym = syms.unnamedModule;
2.38 } else {
2.39 - msym = readModule(fo);
2.40 + try {
2.41 + msym = readModule(fo);
2.42 + } catch (CompletionFailure ex) {
2.43 + chk.completionError(null, ex);
2.44 + msym = syms.unnamedModule;
2.45 + }
2.46 +
2.47 }
2.48
2.49 if (msym.patchLocation == null) {
3.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Jun 26 10:38:22 2017 +0200
3.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Jul 31 11:07:41 2017 +0200
3.3 @@ -290,8 +290,7 @@
3.4 */
3.5 public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
3.6 log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
3.7 - if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
3.8 - else return syms.errType;
3.9 + return syms.errType;
3.10 }
3.11
3.12 /** Report an error that wrong type tag was found.
4.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon Jun 26 10:38:22 2017 +0200
4.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon Jul 31 11:07:41 2017 +0200
4.3 @@ -94,10 +94,8 @@
4.4 import com.sun.tools.javac.tree.JCTree.JCUses;
4.5 import com.sun.tools.javac.tree.JCTree.Tag;
4.6 import com.sun.tools.javac.tree.TreeInfo;
4.7 -import com.sun.tools.javac.util.Abort;
4.8 import com.sun.tools.javac.util.Assert;
4.9 import com.sun.tools.javac.util.Context;
4.10 -import com.sun.tools.javac.util.JCDiagnostic;
4.11 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
4.12 import com.sun.tools.javac.util.List;
4.13 import com.sun.tools.javac.util.ListBuffer;
4.14 @@ -105,7 +103,6 @@
4.15 import com.sun.tools.javac.util.Name;
4.16 import com.sun.tools.javac.util.Names;
4.17 import com.sun.tools.javac.util.Options;
4.18 -import com.sun.tools.javac.util.Position;
4.19
4.20 import static com.sun.tools.javac.code.Flags.ABSTRACT;
4.21 import static com.sun.tools.javac.code.Flags.ENUM;
4.22 @@ -293,8 +290,7 @@
4.23 msym.complete();
4.24 }
4.25 } catch (CompletionFailure ex) {
4.26 - log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, Position.NOPOS, "cant.access", ex.sym, ex.getDetailValue());
4.27 - if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
4.28 + chk.completionError(null, ex);
4.29 } finally {
4.30 depth--;
4.31 }
4.32 @@ -1283,10 +1279,6 @@
4.33 Predicate<ModuleSymbol> observablePred = sym ->
4.34 (observable == null) ? (moduleFinder.findModule(sym).kind != ERR) : observable.contains(sym);
4.35 Predicate<ModuleSymbol> systemModulePred = sym -> (sym.flags() & Flags.SYSTEM_MODULE) != 0;
4.36 - Predicate<ModuleSymbol> noIncubatorPred = sym -> {
4.37 - sym.complete();
4.38 - return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
4.39 - };
4.40 Set<ModuleSymbol> enabledRoot = new LinkedHashSet<>();
4.41
4.42 if (rootModules.contains(syms.unnamedModule)) {
4.43 @@ -1304,9 +1296,18 @@
4.44 jdkModulePred = sym -> true;
4.45 }
4.46
4.47 + Predicate<ModuleSymbol> noIncubatorPred = sym -> {
4.48 + sym.complete();
4.49 + return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
4.50 + };
4.51 +
4.52 for (ModuleSymbol sym : new HashSet<>(syms.getAllModules())) {
4.53 - if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
4.54 - enabledRoot.add(sym);
4.55 + try {
4.56 + if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
4.57 + enabledRoot.add(sym);
4.58 + }
4.59 + } catch (CompletionFailure ex) {
4.60 + chk.completionError(null, ex);
4.61 }
4.62 }
4.63 }
4.64 @@ -1398,32 +1399,36 @@
4.65 result.add(syms.java_base);
4.66
4.67 while (primaryTodo.nonEmpty() || secondaryTodo.nonEmpty()) {
4.68 - ModuleSymbol current;
4.69 - boolean isPrimaryTodo;
4.70 - if (primaryTodo.nonEmpty()) {
4.71 - current = primaryTodo.head;
4.72 - primaryTodo = primaryTodo.tail;
4.73 - isPrimaryTodo = true;
4.74 - } else {
4.75 - current = secondaryTodo.head;
4.76 - secondaryTodo = secondaryTodo.tail;
4.77 - isPrimaryTodo = false;
4.78 - }
4.79 - if (observable != null && !observable.contains(current))
4.80 - continue;
4.81 - if (!result.add(current) || current == syms.unnamedModule || ((current.flags_field & Flags.AUTOMATIC_MODULE) != 0))
4.82 - continue;
4.83 - current.complete();
4.84 - if (current.kind == ERR && isPrimaryTodo && warnedMissing.add(current)) {
4.85 - log.error(Errors.ModuleNotFound(current));
4.86 - }
4.87 - for (RequiresDirective rd : current.requires) {
4.88 - if (rd.module == syms.java_base) continue;
4.89 - if ((rd.isTransitive() && isPrimaryTodo) || base.contains(current)) {
4.90 - primaryTodo = primaryTodo.prepend(rd.module);
4.91 + try {
4.92 + ModuleSymbol current;
4.93 + boolean isPrimaryTodo;
4.94 + if (primaryTodo.nonEmpty()) {
4.95 + current = primaryTodo.head;
4.96 + primaryTodo = primaryTodo.tail;
4.97 + isPrimaryTodo = true;
4.98 } else {
4.99 - secondaryTodo = secondaryTodo.prepend(rd.module);
4.100 + current = secondaryTodo.head;
4.101 + secondaryTodo = secondaryTodo.tail;
4.102 + isPrimaryTodo = false;
4.103 }
4.104 + if (observable != null && !observable.contains(current))
4.105 + continue;
4.106 + if (!result.add(current) || current == syms.unnamedModule || ((current.flags_field & Flags.AUTOMATIC_MODULE) != 0))
4.107 + continue;
4.108 + current.complete();
4.109 + if (current.kind == ERR && isPrimaryTodo && warnedMissing.add(current)) {
4.110 + log.error(Errors.ModuleNotFound(current));
4.111 + }
4.112 + for (RequiresDirective rd : current.requires) {
4.113 + if (rd.module == syms.java_base) continue;
4.114 + if ((rd.isTransitive() && isPrimaryTodo) || base.contains(current)) {
4.115 + primaryTodo = primaryTodo.prepend(rd.module);
4.116 + } else {
4.117 + secondaryTodo = secondaryTodo.prepend(rd.module);
4.118 + }
4.119 + }
4.120 + } catch (CompletionFailure ex) {
4.121 + chk.completionError(null, ex);
4.122 }
4.123 }
4.124
5.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Jun 26 10:38:22 2017 +0200
5.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Jul 31 11:07:41 2017 +0200
5.3 @@ -1435,7 +1435,7 @@
5.4 ClassSymbol c = readClassSymbol(nextChar());
5.5 NameAndType nt = readNameAndType(nextChar());
5.6
5.7 - if (c.members_field == null)
5.8 + if (c.members_field == null || c.kind != TYP)
5.9 throw badClassFile("bad.enclosing.class", self, c);
5.10
5.11 MethodSymbol m = findMethod(nt, c.members_field, self.flags());
6.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Jun 26 10:38:22 2017 +0200
6.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Mon Jul 31 11:07:41 2017 +0200
6.3 @@ -408,8 +408,6 @@
6.4 } catch (CompletionFailure ex) {
6.5 // inlined Check.completionError as it is not initialized yet
6.6 log.error("cant.access", ex.sym, ex.getDetailValue());
6.7 - if (ex instanceof ClassFinder.BadClassFile)
6.8 - throw new Abort();
6.9 }
6.10 source = Source.instance(context);
6.11 attr = Attr.instance(context);
7.1 --- a/test/tools/javac/modules/EdgeCases.java Mon Jun 26 10:38:22 2017 +0200
7.2 +++ b/test/tools/javac/modules/EdgeCases.java Mon Jul 31 11:07:41 2017 +0200
7.3 @@ -467,7 +467,8 @@
7.4
7.5 List<String> expected = Arrays.asList(
7.6 "- compiler.err.cant.access: m1x.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.module.name.mismatch: other, m1x))",
7.7 - "1 error");
7.8 + "module-info.java:1:1: compiler.err.module.not.found: m1x",
7.9 + "2 errors");
7.10
7.11 if (!expected.equals(log)) {
7.12 throw new AssertionError("Unexpected output: " + log);