From 9b59e8528822a12f2dd3e1b472160b2adebba5c0 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 15 Dec 2023 08:01:57 +0100 Subject: [PATCH] 8322159: ThisEscapeAnalyzer crashes for erroneous code --- .../tools/javac/comp/ThisEscapeAnalyzer.java | 8 +++- .../tools/javac/recovery/AttrRecovery.java | 39 ++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 0dd32fd8eca52..f6ce19fac06e5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -506,7 +506,7 @@ public void visitMethodDef(JCMethodDecl tree) { public void visitApply(JCMethodInvocation invoke) { // Get method symbol - MethodSymbol sym = (MethodSymbol)TreeInfo.symbolFor(invoke.meth); + Symbol sym = TreeInfo.symbolFor(invoke.meth); // Recurse on method expression scan(invoke.meth); @@ -530,7 +530,7 @@ public void visitApply(JCMethodInvocation invoke) { invoke(invoke, sym, invoke.args, receiverRefs); } - private void invoke(JCTree site, MethodSymbol sym, List args, RefSet receiverRefs) { + private void invoke(JCTree site, Symbol sym, List args, RefSet receiverRefs) { // Skip if ignoring warnings for a constructor invoked via 'this()' if (suppressed.contains(sym)) @@ -810,6 +810,10 @@ public void visitSelect(JCFieldAccess tree) { @Override public void visitReference(JCMemberReference tree) { + if (tree.type.isErroneous()) { + //error recovery - ignore erroneous member references + return ; + } // Scan target expression and extract 'this' references, if any scan(tree.expr); diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index 607575b291fca..2ab92a625d0e1 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8301580 + * @bug 8301580 8322159 * @summary Verify error recovery w.r.t. Attr * @library /tools/lib * @enablePreview @@ -87,4 +87,41 @@ class C { } } + @Test + public void testX() throws Exception { + String code = """ + public class C { + public C() { + Undefined.method(); + undefined1(); + Runnable r = this::undefined2; + overridable(this); //to verify ThisEscapeAnalyzer has been run + } + public void overridable(C c) {} + } + """; + Path curPath = Path.of("."); + List actual = new JavacTask(tb) + .options("-XDrawDiagnostics", "-XDdev", + "-XDshould-stop.at=FLOW", "-Xlint:this-escape") + .sources(code) + .outdir(curPath) + .run(Expect.FAIL) + .writeAll() + .getOutputLines(OutputKind.DIRECT); + + List expected = List.of( + "C.java:3:9: compiler.err.cant.resolve.location: kindname.variable, Undefined, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:4:9: compiler.err.cant.resolve.location.args: kindname.method, undefined1, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:5:22: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, undefined2, , , (compiler.misc.location: kindname.class, C, null))", + "C.java:6:20: compiler.warn.possible.this.escape", + "3 errors", + "1 warning" + ); + + if (!Objects.equals(actual, expected)) { + error("Expected: " + expected + ", but got: " + actual); + } + } + }