8029102: Enhance compiler warnings for Lambda
Reviewed-by: briangoetz, jjg, jlahoda, ahgross
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Apr 25 22:00:58 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Apr 28 14:48:51 2014 +0100
@@ -383,7 +383,7 @@
/** A class is an inner class if it it has an enclosing instance class.
*/
public boolean isInner() {
- return type.getEnclosingType().hasTag(CLASS);
+ return kind == TYP && type.getEnclosingType().hasTag(CLASS);
}
/** An inner class has an outer instance if it is not an interface
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Apr 25 22:00:58 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Apr 28 14:48:51 2014 +0100
@@ -2141,6 +2141,11 @@
cdef.extending = clazz;
}
+ if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
+ isSerializable(clazztype)) {
+ localEnv.info.isSerializable = true;
+ }
+
attribStat(cdef, localEnv);
checkLambdaCandidate(tree, cdef.sym, clazztype);
@@ -2296,6 +2301,9 @@
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
try {
Type currentTarget = pt();
+ if (needsRecovery && isSerializable(currentTarget)) {
+ localEnv.info.isSerializable = true;
+ }
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
@@ -2700,17 +2708,20 @@
typeargtypes = attribTypes(that.typeargs, localEnv);
}
- Type target;
Type desc;
- if (pt() != Type.recoveryType) {
- target = targetChecker.visit(pt(), that);
- desc = types.findDescriptorType(target);
+ Type currentTarget = pt();
+ boolean isTargetSerializable =
+ resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
+ isSerializable(currentTarget);
+ if (currentTarget != Type.recoveryType) {
+ currentTarget = targetChecker.visit(currentTarget, that);
+ desc = types.findDescriptorType(currentTarget);
} else {
- target = Type.recoveryType;
+ currentTarget = Type.recoveryType;
desc = fallbackDescriptorType(that);
}
- setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext);
+ setFunctionalInfo(localEnv, that, pt(), desc, currentTarget, resultInfo.checkContext);
List<Type> argtypes = desc.getParameterTypes();
Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck;
@@ -2761,10 +2772,10 @@
JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that,
"invalid.mref", Kinds.kindName(that.getMode()), detailsDiag);
- if (targetError && target == Type.recoveryType) {
+ if (targetError && currentTarget == Type.recoveryType) {
//a target error doesn't make sense during recovery stage
//as we don't know what actual parameter types are
- result = that.type = target;
+ result = that.type = currentTarget;
return;
} else {
if (targetError) {
@@ -2772,7 +2783,7 @@
} else {
log.report(diag);
}
- result = that.type = types.createErrorType(target);
+ result = that.type = types.createErrorType(currentTarget);
return;
}
}
@@ -2783,7 +2794,7 @@
if (desc.getReturnType() == Type.recoveryType) {
// stop here
- result = that.type = target;
+ result = that.type = currentTarget;
return;
}
@@ -2801,7 +2812,7 @@
//static ref with class type-args
log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
diags.fragment("static.mref.with.targs"));
- result = that.type = types.createErrorType(target);
+ result = that.type = types.createErrorType(currentTarget);
return;
}
@@ -2810,7 +2821,7 @@
//no static bound mrefs
log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
diags.fragment("static.bound.mref"));
- result = that.type = types.createErrorType(target);
+ result = that.type = types.createErrorType(currentTarget);
return;
}
@@ -2818,6 +2829,10 @@
// Check that super-qualified symbols are not abstract (JLS)
rs.checkNonAbstract(that.pos(), that.sym);
}
+
+ if (isTargetSerializable) {
+ chk.checkElemAccessFromSerializableLambda(that);
+ }
}
ResultInfo checkInfo =
@@ -2849,9 +2864,9 @@
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
if (!isSpeculativeRound) {
- checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, target);
+ checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget);
}
- result = check(that, target, VAL, resultInfo);
+ result = check(that, currentTarget, VAL, resultInfo);
} catch (Types.FunctionDescriptorLookupError ex) {
JCDiagnostic cause = ex.getDiagnostic();
resultInfo.checkContext.report(that, cause);
@@ -3191,6 +3206,11 @@
while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
env1 = env1.outer;
}
+
+ if (env.info.isSerializable) {
+ chk.checkElemAccessFromSerializableLambda(tree);
+ }
+
result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
}
@@ -3315,6 +3335,10 @@
}
}
+ if (env.info.isSerializable) {
+ chk.checkElemAccessFromSerializableLambda(tree);
+ }
+
env.info.selectSuper = selectSuperPrev;
result = checkId(tree, site, sym, env, resultInfo);
}
@@ -4181,6 +4205,11 @@
((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
log.error(env.tree.pos(), "enum.types.not.extensible");
}
+
+ if (isSerializable(c.type)) {
+ env.info.isSerializable = true;
+ }
+
attribClassBody(env, c);
chk.checkDeprecatedAnnotation(env.tree.pos(), c);
@@ -4294,7 +4323,7 @@
// Check for proper use of serialVersionUID
if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
- isSerializable(c) &&
+ isSerializable(c.type) &&
(c.flags() & Flags.ENUM) == 0 &&
checkForSerial(c)) {
checkSerialVersionUID(tree, c);
@@ -4334,15 +4363,15 @@
return null;
}
- /** check if a class is a subtype of Serializable, if that is available. */
- private boolean isSerializable(ClassSymbol c) {
+ /** check if a type is a subtype of Serializable, if that is available. */
+ boolean isSerializable(Type t) {
try {
syms.serializableType.complete();
}
catch (CompletionFailure e) {
return false;
}
- return types.isSubtype(c.type, syms.serializableType);
+ return types.isSubtype(t, syms.serializableType);
}
/** Check that an appropriate serialVersionUID member is defined. */
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Apr 25 22:00:58 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Mon Apr 28 14:48:51 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -54,6 +54,10 @@
*/
boolean selectSuper = false;
+ /** Is the current target of lambda expression or method reference serializable?
+ */
+ boolean isSerializable = false;
+
/** Are arguments to current function applications boxed into an array for varargs?
*/
Resolve.MethodResolutionPhase pendingResolutionPhase = null;
@@ -89,6 +93,7 @@
info.enclVar = enclVar;
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
+ info.isSerializable = isSerializable;
return info;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Apr 25 22:00:58 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Apr 28 14:48:51 2014 +0100
@@ -81,6 +81,7 @@
private final TreeInfo treeinfo;
private final JavaFileManager fileManager;
private final Profile profile;
+ private final boolean warnOnAccessToSensitiveMembers;
// The set of lint options currently in effect. It is initialized
// from the context, and then is set/reset as needed by Attr as it
@@ -130,6 +131,7 @@
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
+ warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
Target target = Target.instance(context);
syntheticNameChar = target.syntheticNameChar();
@@ -2588,6 +2590,44 @@
}
}
+ void checkElemAccessFromSerializableLambda(final JCTree tree) {
+ if (warnOnAccessToSensitiveMembers) {
+ Symbol sym = TreeInfo.symbol(tree);
+ if ((sym.kind & (VAR | MTH)) == 0) {
+ return;
+ }
+
+ if (sym.kind == VAR) {
+ if ((sym.flags() & PARAMETER) != 0 ||
+ sym.isLocal() ||
+ sym.name == names._this ||
+ sym.name == names._super) {
+ return;
+ }
+ }
+
+ if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
+ isEffectivelyNonPublic(sym)) {
+ log.warning(tree.pos(),
+ "access.to.sensitive.member.from.serializable.element", sym);
+ }
+ }
+ }
+
+ private boolean isEffectivelyNonPublic(Symbol sym) {
+ if (sym.packge() == syms.rootPackage) {
+ return false;
+ }
+
+ while (sym.kind != Kinds.PCK) {
+ if ((sym.flags() & PUBLIC) == 0) {
+ return true;
+ }
+ sym = sym.owner;
+ }
+ return false;
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Apr 25 22:00:58 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Apr 28 14:48:51 2014 +0100
@@ -1627,6 +1627,10 @@
compiler.warn.varargs.redundant.trustme.anno=\
Redundant {0} annotation. {1}
+# 0: symbol
+compiler.warn.access.to.sensitive.member.from.serializable.element=\
+ access to sensitive member {0} from serializable element can be publicly accessible to untrusted code
+
#####
## The following are tokens which are non-terminals in the language. They should
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Fri Apr 25 22:00:58 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Mon Apr 28 14:48:51 2014 +0100
@@ -851,6 +851,8 @@
return symbol(((JCTypeApply) tree).clazz);
case ANNOTATED_TYPE:
return symbol(((JCAnnotatedType) tree).underlyingType);
+ case REFERENCE:
+ return ((JCMemberReference) tree).sym;
default:
return null;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java Mon Apr 28 14:48:51 2014 +0100
@@ -0,0 +1,241 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8029102
+ * @summary Enhance compiler warnings for Lambda
+ * Checks that the warning for accessing non public members of a class is
+ * fired correctly.
+ * @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java
+ */
+
+import java.io.Serializable;
+
+public class WarnSerializableLambdaTest {
+
+ void warnLambda() throws Exception {
+ SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod;
+ SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod;
+ SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod;
+
+ WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
+ SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
+ SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
+ SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
+
+ SAM t9 = (SAM & Serializable) c -> {
+
+ WarnSerializableLambdaTest.staticPackageField = "";
+ WarnSerializableLambdaTest.staticProtectedField = "";
+ WarnSerializableLambdaTest.staticPrivateField = "";
+
+ packageField = "";
+ protectedField = "";
+ privateField = "";
+
+ WarnSerializableLambdaTest.packageClassMethod(null);
+ WarnSerializableLambdaTest.protectedClassMethod(null);
+ WarnSerializableLambdaTest.privateClassMethod(null);
+
+ packageInstanceMethod(null);
+ protectedInstanceMethod(null);
+ privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+
+ return null;
+ };
+ }
+
+ private void warnAnoInnerClass() throws Exception {
+ new SerializableDesc() {
+ public void m(Object param) throws Exception {
+ WarnSerializableLambdaTest.staticPackageField = "";
+ WarnSerializableLambdaTest.staticProtectedField = "";
+ WarnSerializableLambdaTest.staticPrivateField = "";
+
+ packageField = "";
+ protectedField = "";
+ privateField = "";
+
+ WarnSerializableLambdaTest.packageClassMethod(null);
+ WarnSerializableLambdaTest.protectedClassMethod(null);
+ WarnSerializableLambdaTest.privateClassMethod(null);
+
+ packageInstanceMethod(null);
+ protectedInstanceMethod(null);
+ privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+ }
+ };
+ }
+
+ void dontWarnLambda() throws Exception {
+ SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod;
+
+ WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
+ SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
+
+ int[] buffer = {0};
+
+ SAM t3 = (SAM & Serializable) param -> {
+ Object localVar;
+ localVar = null;
+ param = null;
+
+ WarnSerializableLambdaTest.staticPublicField = "";
+ publicField = "";
+ WarnSerializableLambdaTest.publicClassMethod(null);
+ publicInstanceMethod(null);
+
+ PublicClass.effectivelyPublicStaticField = "";
+ PublicClass.effectivelyPublicClassMethod();
+
+ PublicClass p = new PublicClass();
+ p.effectivelyPublicInstanceField = "";
+ p.effectivelyPublicInstanceMethod();
+
+ int l = buffer.length;
+
+ return null;
+ };
+ }
+
+ private void dontWarnAnoInnerClass() throws Exception {
+ final int[] buffer = {0};
+ new SerializableDesc() {
+ public void m(Object param) throws Exception {
+ Object localVar;
+ localVar = null;
+ param = null;
+
+ WarnSerializableLambdaTest.staticPublicField = "";
+ publicField = "";
+ WarnSerializableLambdaTest.publicClassMethod(null);
+ publicInstanceMethod(null);
+
+ PublicClass.effectivelyPublicStaticField = "";
+ PublicClass.effectivelyPublicClassMethod();
+
+ PublicClass p = new PublicClass();
+ p.effectivelyPublicInstanceField = "";
+ p.effectivelyPublicInstanceMethod();
+
+ int l = buffer.length;
+ }
+ };
+ }
+
+ enum WarnEnum {
+ A {
+ public void m() throws Exception {
+ WarnSerializableLambdaTest.staticPackageField = "";
+ WarnSerializableLambdaTest.staticProtectedField = "";
+ WarnSerializableLambdaTest.staticPrivateField = "";
+
+ WarnSerializableLambdaTest test =
+ new WarnSerializableLambdaTest();
+
+ test.packageField = "";
+ test.protectedField = "";
+ test.privateField = "";
+
+ WarnSerializableLambdaTest.packageClassMethod(null);
+ WarnSerializableLambdaTest.protectedClassMethod(null);
+ WarnSerializableLambdaTest.privateClassMethod(null);
+
+ test.packageInstanceMethod(null);
+ test.protectedInstanceMethod(null);
+ test.privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+ }
+ };
+
+ public void m() throws Exception {}
+ }
+
+ static String staticPackageField;
+ static private String staticPrivateField;
+ static protected String staticProtectedField;
+ static public String staticPublicField;
+
+ String packageField;
+ private String privateField;
+ protected String protectedField;
+ public String publicField;
+
+ static Object packageClassMethod(String s) {
+ return null;
+ }
+
+ static private Object privateClassMethod(String s) {
+ return null;
+ }
+
+ static protected Object protectedClassMethod(String s) {
+ return null;
+ }
+
+ static public Object publicClassMethod(String s) {
+ return null;
+ }
+
+ Object packageInstanceMethod(String s) {
+ return null;
+ }
+
+ protected Object protectedInstanceMethod(String s) {
+ return null;
+ }
+
+ private Object privateInstanceMethod(String s) {
+ return null;
+ }
+
+ public Object publicInstanceMethod(String s) {
+ return null;
+ }
+
+ interface SAM {
+ Object apply(String s) throws Exception;
+ }
+
+ interface SAM2 {
+ Object apply(String arg1, String arg2);
+ }
+
+ class SerializableDesc implements Serializable {
+ public void m(Object param) throws Exception {}
+ }
+
+ static private class PrivateClass {
+ static public String effectivelyNonPublicStaticField;
+ public String effectivelyNonPublicInstanceField;
+
+ static public void effectivelyNonPublicClassMethod() {}
+ public void effectivelyNonPublicInstanceMethod() {}
+ }
+
+ static public class PublicClass {
+ static public String effectivelyPublicStaticField;
+ public String effectivelyPublicInstanceField;
+
+ static public void effectivelyPublicClassMethod() {}
+ public void effectivelyPublicInstanceMethod() {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out Mon Apr 28 14:48:51 2014 +0100
@@ -0,0 +1,57 @@
+WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
+WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
+WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
+WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
+WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
+WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
+WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
+WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
+WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
+WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
+WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
+WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
+WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
+WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
+WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
+WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
+WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
+WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
+WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+- compiler.err.warnings.and.werror
+1 error
+54 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java Mon Apr 28 14:48:51 2014 +0100
@@ -0,0 +1,56 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8029102
+ * @summary Enhance compiler warnings for Lambda
+ * Checks that the warning for accessing non public members of a class is
+ * fired correctly.
+ * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java
+ */
+
+import java.io.Serializable;
+
+public class WarnSerializableLambdaTestb {
+ public void foo(Secret1 secret) {
+ Object o = (Runnable & java.io.Serializable) () -> { secret.test(); };
+ }
+
+ public void bar(Secret2 secret) {
+ Object o = (Runnable & java.io.Serializable) () -> { secret.test(); };
+ }
+
+ private class Secret1 {
+ public void test() {}
+ }
+
+ static private class Secret2 {
+ public void test() {}
+ }
+
+ class TestInner {
+ private int j = 0;
+ void m() {
+ Serializable s = new Serializable() {
+ int i;
+ void m() {
+ i = 0; // don't warn
+ System.out.println(j); //warn
+ }
+ };
+ }
+ }
+
+ class TestInner2 {
+ class W implements Serializable {
+ public int p = 0;
+ class I {
+ public int r = 0;
+ class K implements Serializable {
+ void m() {
+ p = 1; // don't warn owner is serializable
+ r = 2; // warn owner is not serializable
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out Mon Apr 28 14:48:51 2014 +0100
@@ -0,0 +1,7 @@
+WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
+WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
+WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j
+WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r
+- compiler.err.warnings.and.werror
+1 error
+4 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java Mon Apr 28 14:48:51 2014 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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.access.to.sensitive.member.from.serializable.element
+// options: -XDwarnOnAccessToSensitiveMembers
+
+import java.io.Serializable;
+
+public class WarnSerializableLambda {
+ interface SAM {
+ void apply(String s);
+ }
+
+ private void m1() {
+ SAM s = (SAM & Serializable) c -> {
+ packageField = "";
+ };
+ }
+
+ String packageField;
+}