Skip to content

Commit 27646e5

Browse files
committed
8344148: Add an explicit compiler phase for warning generation
Reviewed-by: vromero
1 parent 8d388cc commit 27646e5

File tree

19 files changed

+219
-30
lines changed

19 files changed

+219
-30
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -58,11 +58,12 @@ public enum CompileState {
5858
PROCESS(3),
5959
ATTR(4),
6060
FLOW(5),
61-
TRANSTYPES(6),
62-
TRANSPATTERNS(7),
63-
LOWER(8),
64-
UNLAMBDA(9),
65-
GENERATE(10);
61+
WARN(6),
62+
TRANSTYPES(7),
63+
TRANSPATTERNS(8),
64+
LOWER(9),
65+
UNLAMBDA(10),
66+
GENERATE(11);
6667

6768
CompileState(int value) {
6869
this.value = value;

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -229,7 +229,6 @@ public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
229229
new AssignAnalyzer().analyzeTree(env, make);
230230
new FlowAnalyzer().analyzeTree(env, make);
231231
new CaptureAnalyzer().analyzeTree(env, make);
232-
new ThisEscapeAnalyzer(names, syms, types, rs, log, lint).analyzeTree(env);
233232
}
234233

235234
public void analyzeLambda(Env<AttrContext> env, JCLambda that, TreeMaker make, boolean speculative) {

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,7 @@
5858
import com.sun.tools.javac.tree.TreeInfo;
5959
import com.sun.tools.javac.tree.TreeScanner;
6060
import com.sun.tools.javac.util.Assert;
61+
import com.sun.tools.javac.util.Context;
6162
import com.sun.tools.javac.util.JCDiagnostic;
6263
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
6364
import com.sun.tools.javac.util.List;
@@ -140,8 +141,17 @@
140141
* <li>We assume that native methods do not leak.
141142
* <li>We don't try to follow {@code super()} invocations; that's for the superclass analysis to handle.
142143
* </ul>
144+
*
145+
* <p><b>This is NOT part of any supported API.
146+
* If you write code that depends on this, you do so at your own risk.
147+
* This code and its internal interfaces are subject to change or
148+
* deletion without notice.</b>
143149
*/
144-
class ThisEscapeAnalyzer extends TreeScanner {
150+
public class ThisEscapeAnalyzer extends TreeScanner {
151+
152+
protected static final Context.Key<ThisEscapeAnalyzer> contextKey = new Context.Key<>();
153+
154+
// Other singletons we utilize
145155

146156
private final Names names;
147157
private final Symtab syms;
@@ -211,22 +221,49 @@ class ThisEscapeAnalyzer extends TreeScanner {
211221
*/
212222
private RefSet<Ref> refs;
213223

214-
// Constructor
224+
// Access
215225

216-
ThisEscapeAnalyzer(Names names, Symtab syms, Types types, Resolve rs, Log log, Lint lint) {
217-
this.names = names;
218-
this.syms = syms;
219-
this.types = types;
220-
this.rs = rs;
221-
this.log = log;
222-
this.lint = lint;
226+
public static ThisEscapeAnalyzer instance(Context context) {
227+
ThisEscapeAnalyzer instance = context.get(contextKey);
228+
if (instance == null)
229+
instance = new ThisEscapeAnalyzer(context);
230+
return instance;
231+
}
232+
233+
@SuppressWarnings("this-escape")
234+
protected ThisEscapeAnalyzer(Context context) {
235+
context.put(contextKey, this);
236+
names = Names.instance(context);
237+
log = Log.instance(context);
238+
syms = Symtab.instance(context);
239+
types = Types.instance(context);
240+
rs = Resolve.instance(context);
241+
lint = Lint.instance(context);
223242
}
224243

225244
//
226245
// Main method
227246
//
228247

229248
public void analyzeTree(Env<AttrContext> env) {
249+
try {
250+
doAnalyzeTree(env);
251+
} finally {
252+
attrEnv = null;
253+
methodMap.clear();
254+
nonPublicOuters.clear();
255+
targetClass = null;
256+
warningList.clear();
257+
methodClass = null;
258+
callStack.clear();
259+
invocations.clear();
260+
pendingWarning = null;
261+
depth = -1;
262+
refs = null;
263+
}
264+
}
265+
266+
private void doAnalyzeTree(Env<AttrContext> env) {
230267

231268
// Sanity check
232269
Assert.check(checkInvariants(false, false));

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1168,7 +1168,7 @@ private Type erasure(Type t) {
11681168
private Env<AttrContext> env;
11691169

11701170
private static final String statePreviousToFlowAssertMsg =
1171-
"The current compile state [%s] of class %s is previous to FLOW";
1171+
"The current compile state [%s] of class %s is previous to WARN";
11721172

11731173
void translateClass(ClassSymbol c) {
11741174
Type st = types.supertype(c.type);
@@ -1189,15 +1189,15 @@ void translateClass(ClassSymbol c) {
11891189
* 1) has no compile state being it the most outer class.
11901190
* We accept this condition for inner classes.
11911191
*
1192-
* 2) has a compile state which is previous to Flow state.
1192+
* 2) has a compile state which is previous to WARN state.
11931193
*/
11941194
boolean envHasCompState = compileStates.get(myEnv) != null;
11951195
if (!envHasCompState && c.outermostClass() == c) {
11961196
Assert.error("No info for outermost class: " + myEnv.enclClass.sym);
11971197
}
11981198

11991199
if (envHasCompState &&
1200-
CompileState.FLOW.isAfter(compileStates.get(myEnv))) {
1200+
CompileState.WARN.isAfter(compileStates.get(myEnv))) {
12011201
Assert.error(String.format(statePreviousToFlowAssertMsg,
12021202
compileStates.get(myEnv), myEnv.enclClass.sym));
12031203
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package com.sun.tools.javac.comp;
27+
28+
import com.sun.tools.javac.util.Context;
29+
import com.sun.tools.javac.util.Log;
30+
31+
/** This pass checks for various things to warn about.
32+
* It runs after attribution and flow analysis.
33+
*
34+
* <p><b>This is NOT part of any supported API.
35+
* If you write code that depends on this, you do so at your own risk.
36+
* This code and its internal interfaces are subject to change or
37+
* deletion without notice.</b>
38+
*/
39+
public class WarningAnalyzer {
40+
41+
protected static final Context.Key<WarningAnalyzer> contextKey = new Context.Key<>();
42+
43+
private final Log log;
44+
private final ThisEscapeAnalyzer thisEscapeAnalyzer;
45+
46+
public static WarningAnalyzer instance(Context context) {
47+
WarningAnalyzer instance = context.get(contextKey);
48+
if (instance == null)
49+
instance = new WarningAnalyzer(context);
50+
return instance;
51+
}
52+
53+
@SuppressWarnings("this-escape")
54+
protected WarningAnalyzer(Context context) {
55+
context.put(contextKey, this);
56+
log = Log.instance(context);
57+
thisEscapeAnalyzer = ThisEscapeAnalyzer.instance(context);
58+
}
59+
60+
public void analyzeTree(Env<AttrContext> env) {
61+
thisEscapeAnalyzer.analyzeTree(env);
62+
}
63+
}

src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -306,6 +306,10 @@ else if (option.equals("class"))
306306
*/
307307
protected Flow flow;
308308

309+
/** The warning analyzer.
310+
*/
311+
protected WarningAnalyzer warningAnalyzer;
312+
309313
/** The modules visitor
310314
*/
311315
protected Modules modules;
@@ -419,6 +423,7 @@ public JavaCompiler(Context context) {
419423
chk = Check.instance(context);
420424
gen = Gen.instance(context);
421425
flow = Flow.instance(context);
426+
warningAnalyzer = WarningAnalyzer.instance(context);
422427
transTypes = TransTypes.instance(context);
423428
lower = Lower.instance(context);
424429
annotate = Annotate.instance(context);
@@ -962,20 +967,20 @@ public void compile(Collection<JavaFileObject> sourceFileObjects,
962967
if (!CompileState.ATTR.isAfter(shouldStopPolicyIfNoError)) {
963968
switch (compilePolicy) {
964969
case SIMPLE:
965-
generate(desugar(flow(attribute(todo))));
970+
generate(desugar(warn(flow(attribute(todo)))));
966971
break;
967972

968973
case BY_FILE: {
969974
Queue<Queue<Env<AttrContext>>> q = todo.groupByFile();
970975
while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) {
971-
generate(desugar(flow(attribute(q.remove()))));
976+
generate(desugar(warn(flow(attribute(q.remove())))));
972977
}
973978
}
974979
break;
975980

976981
case BY_TODO:
977982
while (!todo.isEmpty())
978-
generate(desugar(flow(attribute(todo.remove()))));
983+
generate(desugar(warn(flow(attribute(todo.remove())))));
979984
break;
980985

981986
default:
@@ -1435,6 +1440,56 @@ protected void flow(Env<AttrContext> env, Queue<Env<AttrContext>> results) {
14351440
}
14361441
}
14371442

1443+
/**
1444+
* Check for various things to warn about.
1445+
*
1446+
* @return the list of attributed parse trees
1447+
*/
1448+
public Queue<Env<AttrContext>> warn(Queue<Env<AttrContext>> envs) {
1449+
ListBuffer<Env<AttrContext>> results = new ListBuffer<>();
1450+
for (Env<AttrContext> env: envs) {
1451+
warn(env, results);
1452+
}
1453+
return stopIfError(CompileState.WARN, results);
1454+
}
1455+
1456+
/**
1457+
* Check for various things to warn about in an attributed parse tree.
1458+
*/
1459+
public Queue<Env<AttrContext>> warn(Env<AttrContext> env) {
1460+
ListBuffer<Env<AttrContext>> results = new ListBuffer<>();
1461+
warn(env, results);
1462+
return stopIfError(CompileState.WARN, results);
1463+
}
1464+
1465+
/**
1466+
* Check for various things to warn about in an attributed parse tree.
1467+
*/
1468+
protected void warn(Env<AttrContext> env, Queue<Env<AttrContext>> results) {
1469+
if (compileStates.isDone(env, CompileState.WARN)) {
1470+
results.add(env);
1471+
return;
1472+
}
1473+
1474+
if (shouldStop(CompileState.WARN))
1475+
return;
1476+
1477+
if (verboseCompilePolicy)
1478+
printNote("[warn " + env.enclClass.sym + "]");
1479+
JavaFileObject prev = log.useSource(
1480+
env.enclClass.sym.sourcefile != null ?
1481+
env.enclClass.sym.sourcefile :
1482+
env.toplevel.sourcefile);
1483+
try {
1484+
warningAnalyzer.analyzeTree(env);
1485+
compileStates.put(env, CompileState.WARN);
1486+
results.add(env);
1487+
}
1488+
finally {
1489+
log.useSource(prev);
1490+
}
1491+
}
1492+
14381493
private TaskEvent newAnalyzeTaskEvent(Env<AttrContext> env) {
14391494
JCCompilationUnit toplevel = env.toplevel;
14401495
ClassSymbol sym;
@@ -1493,6 +1548,10 @@ protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>,
14931548
return;
14941549
}
14951550

1551+
// Ensure the file has reached the WARN state
1552+
if (!compileStates.isDone(env, CompileState.WARN))
1553+
warn(env);
1554+
14961555
/**
14971556
* Ensure that superclasses of C are desugared before C itself. This is
14981557
* required for two reasons: (i) as erasure (TransTypes) destroys
@@ -1576,8 +1635,8 @@ public void visitSwitchExpression(JCSwitchExpression tree) {
15761635
ScanNested scanner = new ScanNested();
15771636
scanner.scan(env.tree);
15781637
for (Env<AttrContext> dep: scanner.dependencies) {
1579-
if (!compileStates.isDone(dep, CompileState.FLOW))
1580-
desugaredEnvs.put(dep, desugar(flow(attribute(dep))));
1638+
if (!compileStates.isDone(dep, CompileState.WARN))
1639+
desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep)))));
15811640
}
15821641

15831642
//We need to check for error another time as more classes might

test/langtools/tools/javac/6734819/T6734819a.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
[attribute Y]
22
[flow Y]
3+
[warn Y]
34
[attribute W]
45
[flow W]
6+
[warn W]
57
[attribute Z]
68
[flow Z]
9+
[warn Z]
710
[desugar Z]
811
[desugar W]
912
[desugar Y]

test/langtools/tools/javac/6734819/T6734819b.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
[attribute A]
22
[flow A]
3+
[warn A]
34
[attribute B]
45
[flow B]
6+
[warn B]
57
[desugar B]
68
[desugar A]
79
[generate code A]

test/langtools/tools/javac/6734819/T6734819c.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
[attribute Y]
22
[flow Y]
3+
[warn Y]
34
[attribute W]
45
[flow W]
6+
[warn W]
57
[attribute Z]
68
[flow Z]
79
T6734819c.java:15:11: compiler.err.unreachable.stmt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[attribute Explicit]
22
[flow Explicit]
3+
[warn Explicit]
34
[desugar Explicit]
45
[generate code Explicit]

0 commit comments

Comments
 (0)