8029102: Enhance compiler warnings for Lambda
authorvromero
Mon, 28 Apr 2014 14:48:51 +0100
changeset 24219 e7dc661cafae
parent 24218 9102c46a15dc
child 24220 eb213562268d
8029102: Enhance compiler warnings for Lambda Reviewed-by: briangoetz, jjg, jlahoda, ahgross
langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java
langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out
langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java
langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out
langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java
--- 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;
+}