8317376: Minor improvements to the 'this' escape analyzer
Reviewed-by: vromero
This commit is contained in:
parent
4895a15a77
commit
064628471b
@ -53,7 +53,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JIGSAW_TOOLS, \
|
|||||||
build/tools/jigsaw, \
|
build/tools/jigsaw, \
|
||||||
COPY := .properties .html, \
|
COPY := .properties .html, \
|
||||||
BIN := $(TOOLS_CLASSES_DIR), \
|
BIN := $(TOOLS_CLASSES_DIR), \
|
||||||
DISABLED_WARNINGS := fallthrough this-escape, \
|
DISABLED_WARNINGS := fallthrough, \
|
||||||
JAVAC_FLAGS := \
|
JAVAC_FLAGS := \
|
||||||
--add-modules jdk.jdeps \
|
--add-modules jdk.jdeps \
|
||||||
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
#
|
|
||||||
# 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. Oracle designates this
|
|
||||||
# particular file as subject to the "Classpath" exception as provided
|
|
||||||
# by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
@ -23,8 +23,6 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
DOCLINT += -Xdoclint:all/protected \
|
DOCLINT += -Xdoclint:all/protected \
|
||||||
'-Xdoclint/package:java.*,javax.*'
|
'-Xdoclint/package:java.*,javax.*'
|
||||||
CLEAN_FILES += $(wildcard \
|
CLEAN_FILES += $(wildcard \
|
||||||
|
@ -23,6 +23,4 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
COPY += .dat
|
COPY += .dat
|
||||||
|
@ -66,7 +66,7 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \
|
|||||||
SRC := $(TOPDIR)/make/langtools/src/classes, \
|
SRC := $(TOPDIR)/make/langtools/src/classes, \
|
||||||
INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \
|
INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \
|
||||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javac, \
|
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javac, \
|
||||||
DISABLED_WARNINGS := options this-escape, \
|
DISABLED_WARNINGS := options, \
|
||||||
JAVAC_FLAGS := \
|
JAVAC_FLAGS := \
|
||||||
$(COMPILECREATESYMBOLS_ADD_EXPORTS), \
|
$(COMPILECREATESYMBOLS_ADD_EXPORTS), \
|
||||||
))
|
))
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
#
|
|
||||||
# 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. Oracle designates this
|
|
||||||
# particular file as subject to the "Classpath" exception as provided
|
|
||||||
# by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
@ -56,7 +56,7 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \
|
|||||||
$(TOPDIR)/src/jdk.jdeps/share/classes, \
|
$(TOPDIR)/src/jdk.jdeps/share/classes, \
|
||||||
INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \
|
INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \
|
||||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc, \
|
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc, \
|
||||||
DISABLED_WARNINGS := options this-escape, \
|
DISABLED_WARNINGS := options, \
|
||||||
JAVAC_FLAGS := \
|
JAVAC_FLAGS := \
|
||||||
$(INTERIM_LANGTOOLS_ARGS) \
|
$(INTERIM_LANGTOOLS_ARGS) \
|
||||||
$(COMPILECREATESYMBOLS_ADD_EXPORTS), \
|
$(COMPILECREATESYMBOLS_ADD_EXPORTS), \
|
||||||
|
@ -23,6 +23,4 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
COPY += _options
|
COPY += _options
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
COPY += .gif .png
|
COPY += .gif .png
|
||||||
|
|
||||||
CLEAN_FILES += $(wildcard \
|
CLEAN_FILES += $(wildcard \
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
include GensrcCommon.gmk
|
include GensrcCommon.gmk
|
||||||
include GensrcProperties.gmk
|
include GensrcProperties.gmk
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
$(eval $(call SetupVersionProperties, JAVAP_VERSION, \
|
$(eval $(call SetupVersionProperties, JAVAP_VERSION, \
|
||||||
com/sun/tools/javap/resources/version.properties))
|
com/sun/tools/javap/resources/version.properties))
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
include LauncherCommon.gmk
|
include LauncherCommon.gmk
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
## Build javap
|
## Build javap
|
||||||
################################################################################
|
################################################################################
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
EXCLUDES += \
|
EXCLUDES += \
|
||||||
com/sun/tools/example/debug/bdi \
|
com/sun/tools/example/debug/bdi \
|
||||||
com/sun/tools/example/debug/event \
|
com/sun/tools/example/debug/event \
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
COPY += .gif .png .txt .spec .script .prerm .preinst \
|
COPY += .gif .png .txt .spec .script .prerm .preinst \
|
||||||
.postrm .postinst .list .sh .desktop .copyright .control .plist .template \
|
.postrm .postinst .list .sh .desktop .copyright .control .plist .template \
|
||||||
.icns .scpt .wxs .wxl .wxi .ico .bmp .tiff .service
|
.icns .scpt .wxs .wxl .wxi .ico .bmp .tiff .service
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
COPY += _dict _th
|
COPY += _dict _th
|
||||||
# Exclude BreakIterator classes that are just used in compile process to generate
|
# Exclude BreakIterator classes that are just used in compile process to generate
|
||||||
# data files and shouldn't go in the product
|
# data files and shouldn't go in the product
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
DISABLED_WARNINGS_java += this-escape
|
|
||||||
|
|
||||||
# No SCTP implementation on Mac OS X or AIX. These classes should be excluded.
|
# No SCTP implementation on Mac OS X or AIX. These classes should be excluded.
|
||||||
SCTP_IMPL_CLASSES = \
|
SCTP_IMPL_CLASSES = \
|
||||||
$(TOPDIR)/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/AssociationChange.java \
|
$(TOPDIR)/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/AssociationChange.java \
|
||||||
|
@ -231,7 +231,7 @@ public class Flow {
|
|||||||
new AssignAnalyzer().analyzeTree(env, make);
|
new AssignAnalyzer().analyzeTree(env, make);
|
||||||
new FlowAnalyzer().analyzeTree(env, make);
|
new FlowAnalyzer().analyzeTree(env, make);
|
||||||
new CaptureAnalyzer().analyzeTree(env, make);
|
new CaptureAnalyzer().analyzeTree(env, make);
|
||||||
new ThisEscapeAnalyzer(names, syms, types, log, lint).analyzeTree(env);
|
new ThisEscapeAnalyzer(names, syms, types, rs, log, lint).analyzeTree(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void analyzeLambda(Env<AttrContext> env, JCLambda that, TreeMaker make, boolean speculative) {
|
public void analyzeLambda(Env<AttrContext> env, JCLambda that, TreeMaker make, boolean speculative) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -182,6 +182,41 @@ public class TreeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if the given tree is an explicit reference to the 'this' instance of the
|
||||||
|
* class currently being compiled. This is true if tree is:
|
||||||
|
* - An unqualified 'this' identifier
|
||||||
|
* - A 'super' identifier qualified by a class name whose type is 'currentClass' or a supertype
|
||||||
|
* - A 'this' identifier qualified by a class name whose type is 'currentClass' or a supertype
|
||||||
|
* but also NOT an enclosing outer class of 'currentClass'.
|
||||||
|
*/
|
||||||
|
public static boolean isExplicitThisReference(Types types, Type.ClassType currentClass, JCTree tree) {
|
||||||
|
switch (tree.getTag()) {
|
||||||
|
case PARENS:
|
||||||
|
return isExplicitThisReference(types, currentClass, skipParens(tree));
|
||||||
|
case IDENT: {
|
||||||
|
JCIdent ident = (JCIdent)tree;
|
||||||
|
Names names = ident.name.table.names;
|
||||||
|
return ident.name == names._this || ident.name == names._super;
|
||||||
|
}
|
||||||
|
case SELECT: {
|
||||||
|
JCFieldAccess select = (JCFieldAccess)tree;
|
||||||
|
Type selectedType = types.erasure(select.selected.type);
|
||||||
|
if (!selectedType.hasTag(TypeTag.CLASS))
|
||||||
|
return false;
|
||||||
|
Symbol.ClassSymbol currentClassSym = (Symbol.ClassSymbol)((Type.ClassType)types.erasure(currentClass)).tsym;
|
||||||
|
Symbol.ClassSymbol selectedClassSym = (Symbol.ClassSymbol)((Type.ClassType)selectedType).tsym;
|
||||||
|
Names names = select.name.table.names;
|
||||||
|
return currentClassSym.isSubClass(selectedClassSym, types) &&
|
||||||
|
(select.name == names._super ||
|
||||||
|
(select.name == names._this &&
|
||||||
|
(currentClassSym == selectedClassSym ||
|
||||||
|
!currentClassSym.isEnclosedBy(selectedClassSym))));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Is this a call to super?
|
/** Is this a call to super?
|
||||||
*/
|
*/
|
||||||
public static boolean isSuperCall(JCTree tree) {
|
public static boolean isSuperCall(JCTree tree) {
|
||||||
|
@ -313,7 +313,7 @@ public class ThisEscape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Inner2 {
|
public static class Inner2 {
|
||||||
public Inner2() {
|
public Inner2() {
|
||||||
new Test3().mightLeak();
|
new Test3().mightLeak();
|
||||||
}
|
}
|
||||||
@ -585,6 +585,124 @@ public class ThisEscape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape correctly follows outer instances through member classes
|
||||||
|
public static class ThisEscapeOuterRef1 {
|
||||||
|
class Inner {
|
||||||
|
void foo() {
|
||||||
|
ThisEscapeOuterRef1.this.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ThisEscapeOuterRef1() {
|
||||||
|
new Inner().foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape correctly follows outer instances through local classes
|
||||||
|
public static class ThisEscapeOuterRef2 {
|
||||||
|
public ThisEscapeOuterRef2() {
|
||||||
|
class Inner {
|
||||||
|
void foo() {
|
||||||
|
ThisEscapeOuterRef2.this.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new Inner().foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape correctly follows outer instances through anonymous classes
|
||||||
|
public static class ThisEscapeOuterRef3 {
|
||||||
|
public ThisEscapeOuterRef3() {
|
||||||
|
new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
ThisEscapeOuterRef3.this.hashCode(); // leak here
|
||||||
|
}
|
||||||
|
}.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape knows that enhanced for loops invoke iterator(), etc.
|
||||||
|
public static class ThisEscapeForeach1 implements Iterable<Object> {
|
||||||
|
public ThisEscapeForeach1() {
|
||||||
|
for (Object v : this)
|
||||||
|
v.hashCode(); // possible leak here
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public final java.util.Iterator<Object> iterator() {
|
||||||
|
return new java.util.Iterator<Object>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Object next() {
|
||||||
|
return ThisEscapeForeach1.this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape tracks deferred return values
|
||||||
|
public static class DeferredReturn {
|
||||||
|
|
||||||
|
public DeferredReturn(int x) {
|
||||||
|
((Supplier<DeferredReturn>)this::self).get().mightLeak(); // leak here
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeferredReturn(float x) {
|
||||||
|
((Supplier<DeferredReturn>)() -> this).get().mightLeak(); // leak here
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DeferredReturn self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void mightLeak() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape properly tracks variable types
|
||||||
|
public static class TypeTracking {
|
||||||
|
|
||||||
|
public TypeTracking() {
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
TypeTracking.this.mightLeak();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r.run(); // leak here - we know "r" has type TypeTracking$1
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void mightLeak() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape doesn't warn for outer instances of anonymous classes that don't use them
|
||||||
|
public static class ThisEscapeOuterRef4 {
|
||||||
|
public ThisEscapeOuterRef4() {
|
||||||
|
new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
// there is no leak in here
|
||||||
|
}
|
||||||
|
}.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify 'this' escape doesn't warn for doubly-outer instance references
|
||||||
|
public static class ThisEscapeDoubleOuter {
|
||||||
|
public class Inner1 {
|
||||||
|
|
||||||
|
public Inner1() {
|
||||||
|
new Inner2().foo(); // NOT a 'this' leak
|
||||||
|
}
|
||||||
|
|
||||||
|
class Inner2 {
|
||||||
|
void foo() {
|
||||||
|
ThisEscapeDoubleOuter.this.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Verify 'this' escape detection doesn't warn for sealed classes with local permits
|
// Verify 'this' escape detection doesn't warn for sealed classes with local permits
|
||||||
public static sealed class ThisEscapeSealed permits ThisEscapeSealed.Sub1, ThisEscapeSealed.Sub2 {
|
public static sealed class ThisEscapeSealed permits ThisEscapeSealed.Sub1, ThisEscapeSealed.Sub2 {
|
||||||
|
|
||||||
|
@ -23,4 +23,16 @@ ThisEscape.java:396:17: compiler.warn.possible.this.escape
|
|||||||
ThisEscape.java:401:30: compiler.warn.possible.this.escape.location
|
ThisEscape.java:401:30: compiler.warn.possible.this.escape.location
|
||||||
ThisEscape.java:444:28: compiler.warn.possible.this.escape
|
ThisEscape.java:444:28: compiler.warn.possible.this.escape
|
||||||
ThisEscape.java:473:27: compiler.warn.possible.this.escape
|
ThisEscape.java:473:27: compiler.warn.possible.this.escape
|
||||||
25 warnings
|
ThisEscape.java:596:28: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:592:50: compiler.warn.possible.this.escape.location
|
||||||
|
ThisEscape.java:608:28: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:605:54: compiler.warn.possible.this.escape.location
|
||||||
|
ThisEscape.java:619:18: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:617:54: compiler.warn.possible.this.escape.location
|
||||||
|
ThisEscape.java:627:27: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:648:55: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:652:55: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:672:18: compiler.warn.possible.this.escape
|
||||||
|
ThisEscape.java:669:48: compiler.warn.possible.this.escape.location
|
||||||
|
ThisEscape.java:726:32: compiler.warn.possible.this.escape
|
||||||
|
37 warnings
|
||||||
|
Loading…
Reference in New Issue
Block a user