This commit is contained in:
David Dehaven 2014-06-23 13:06:08 -07:00
commit 1207c0efa1
26 changed files with 763 additions and 59 deletions

View File

@ -626,7 +626,7 @@ public class Types {
* (ii) perform functional interface bridge calculation.
*/
public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) {
if (targets.isEmpty() || !isFunctionalInterface(targets.head)) {
if (targets.isEmpty()) {
return null;
}
Symbol descSym = findDescriptorSymbol(targets.head.tsym);
@ -2315,7 +2315,7 @@ public class Types {
public Type visitType(Type t, Void ignored) {
// A note on wildcards: there is no good way to
// determine a supertype for a super bounded wildcard.
return null;
return Type.noType;
}
@Override
@ -2482,7 +2482,7 @@ public class Types {
return false;
return
t.isRaw() ||
supertype(t) != null && isDerivedRaw(supertype(t)) ||
supertype(t) != Type.noType && isDerivedRaw(supertype(t)) ||
isDerivedRaw(interfaces(t));
}
@ -2967,6 +2967,12 @@ public class Types {
return t;
}
@Override
public Type visitUndetVar(UndetVar t, Void ignored) {
//do nothing - we should not replace inside undet variables
return t;
}
@Override
public Type visitClassType(ClassType t, Void ignored) {
if (!t.isCompound()) {

View File

@ -249,36 +249,30 @@ public class Attr extends JCTree.Visitor {
*/
Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
Type owntype = found;
if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
if (allowPoly && inferenceContext.free(found)) {
if ((ownkind & ~resultInfo.pkind) == 0) {
owntype = resultInfo.check(tree, inferenceContext.asUndetVar(owntype));
} else {
log.error(tree.pos(), "unexpected.type",
kindNames(resultInfo.pkind),
kindName(ownkind));
owntype = types.createErrorType(owntype);
}
Type owntype;
if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
if ((ownkind & ~resultInfo.pkind) != 0) {
log.error(tree.pos(), "unexpected.type",
kindNames(resultInfo.pkind),
kindName(ownkind));
owntype = types.createErrorType(found);
} else if (allowPoly && inferenceContext.free(found)) {
//delay the check if there are inference variables in the found type
//this means we are dealing with a partially inferred poly expression
owntype = resultInfo.pt;
inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
@Override
public void typesInferred(InferenceContext inferenceContext) {
ResultInfo pendingResult =
resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
}
});
return tree.type = resultInfo.pt;
} else {
if ((ownkind & ~resultInfo.pkind) == 0) {
owntype = resultInfo.check(tree, owntype);
} else {
log.error(tree.pos(), "unexpected.type",
kindNames(resultInfo.pkind),
kindName(ownkind));
owntype = types.createErrorType(owntype);
}
owntype = resultInfo.check(tree, found);
}
} else {
owntype = found;
}
tree.type = owntype;
return owntype;
@ -2472,6 +2466,7 @@ public class Attr extends JCTree.Visitor {
currentTarget = infer.instantiateFunctionalInterface(that,
currentTarget, explicitParamTypes, resultInfo.checkContext);
}
currentTarget = types.removeWildcards(currentTarget);
lambdaType = types.findDescriptorType(currentTarget);
} else {
currentTarget = Type.recoveryType;
@ -2894,7 +2889,7 @@ public class Attr extends JCTree.Visitor {
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
isSerializable(currentTarget);
if (currentTarget != Type.recoveryType) {
currentTarget = targetChecker.visit(currentTarget, that);
currentTarget = types.removeWildcards(targetChecker.visit(currentTarget, that));
desc = types.findDescriptorType(currentTarget);
} else {
currentTarget = Type.recoveryType;
@ -3135,10 +3130,19 @@ public class Attr extends JCTree.Visitor {
if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
pt != Type.recoveryType) {
//check that functional interface class is well-formed
ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
names.empty, List.of(fExpr.targets.head), ABSTRACT);
if (csym != null) {
chk.checkImplementations(env.tree, csym, csym);
try {
/* Types.makeFunctionalInterfaceClass() may throw an exception
* when it's executed post-inference. See the listener code
* above.
*/
ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
names.empty, List.of(fExpr.targets.head), ABSTRACT);
if (csym != null) {
chk.checkImplementations(env.tree, csym, csym);
}
} catch (Types.FunctionDescriptorLookupError ex) {
JCDiagnostic cause = ex.getDiagnostic();
resultInfo.checkContext.report(env.tree, cause);
}
}
}

View File

@ -534,8 +534,8 @@ public class Check {
Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
final Infer.InferenceContext inferenceContext = checkContext.inferenceContext();
if (inferenceContext.free(req)) {
inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() {
if (inferenceContext.free(req) || inferenceContext.free(found)) {
inferenceContext.addFreeTypeListener(List.of(req, found), new FreeTypeListener() {
@Override
public void typesInferred(InferenceContext inferenceContext) {
checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext);
@ -2684,7 +2684,7 @@ public class Check {
checkClassBounds(pos, seensofar, it);
}
Type st = types.supertype(type);
if (st != null) checkClassBounds(pos, seensofar, st);
if (st != Type.noType) checkClassBounds(pos, seensofar, st);
}
/** Enter interface into into set.

View File

@ -953,7 +953,7 @@ public class DeferredAttr extends JCTree.Visitor {
LambdaReturnScanner() {
super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP,
FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP));
FORLOOP, IF, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP));
}
}

View File

@ -354,6 +354,7 @@ public class Infer {
Type to, Attr.ResultInfo resultInfo,
InferenceContext inferenceContext) {
inferenceContext.solve(List.of(from.qtype), new Warner());
inferenceContext.notifyChange();
Type capturedType = resultInfo.checkContext.inferenceContext()
.cachedCapture(tree, from.inst, false);
if (types.isConvertible(capturedType,
@ -450,7 +451,7 @@ public class Infer {
class ImplicitArgType extends DeferredAttr.DeferredTypeMap {
public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) {
rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
(rs.deferredAttr).super(AttrMode.SPECULATIVE, msym, phase);
}
public Type apply(Type t) {
@ -518,6 +519,8 @@ public class Infer {
//or if it's not a subtype of the original target, issue an error
checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
}
//propagate constraints as per JLS 18.2.1
checkContext.compatible(owntype, funcInterface, types.noWarnings);
return owntype;
}
}

View File

@ -1992,7 +1992,11 @@ public class LambdaToMethod extends TreeTranslator {
// If instance access isn't needed, make it static.
// Interface instance methods must be default methods.
// Lambda methods are private synthetic.
// Inherit ACC_STRICT from the enclosing method, or, for clinit,
// from the class.
translatedSym.flags_field = SYNTHETIC | LAMBDA_METHOD |
owner.flags_field & STRICTFP |
owner.owner.flags_field & STRICTFP |
PRIVATE |
(thisReferenced? (inInterface? DEFAULT : 0) : STATIC);

View File

@ -958,9 +958,10 @@ public class Resolve {
}
public boolean compatible(Type found, Type req, Warner warn) {
InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
return strict ?
types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn) :
types.isConvertible(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn);
types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
}
public void report(DiagnosticPosition pos, JCDiagnostic details) {

View File

@ -412,9 +412,16 @@ public class JavacParser implements Parser {
case ELSE:
case FINALLY:
case CATCH:
case THIS:
case SUPER:
case NEW:
if (stopAtStatement)
return;
break;
case ASSERT:
if (stopAtStatement && allowAsserts)
return ;
break;
}
nextToken();
}
@ -2374,8 +2381,8 @@ public class JavacParser implements Parser {
ListBuffer<JCStatement> stats =
variableDeclarators(mods, t, new ListBuffer<JCStatement>());
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
storeEnd(stats.last(), token.endPos);
accept(SEMI);
storeEnd(stats.last(), S.prevToken().endPos);
return stats.toList();
}
}
@ -2412,13 +2419,14 @@ public class JavacParser implements Parser {
ListBuffer<JCStatement> stats =
variableDeclarators(mods, t, new ListBuffer<JCStatement>());
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
storeEnd(stats.last(), token.endPos);
accept(SEMI);
storeEnd(stats.last(), S.prevToken().endPos);
return stats.toList();
} else {
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
JCExpressionStatement expr = to(F.at(pos).Exec(checkExprStat(t)));
t = checkExprStat(t);
accept(SEMI);
JCExpressionStatement expr = toP(F.at(pos).Exec(t));
return List.<JCStatement>of(expr);
}
}
@ -2497,8 +2505,8 @@ public class JavacParser implements Parser {
JCStatement body = parseStatementAsBlock();
accept(WHILE);
JCExpression cond = parExpression();
JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
accept(SEMI);
JCDoWhileLoop t = toP(F.at(pos).DoLoop(body, cond));
return t;
}
case TRY: {
@ -2546,29 +2554,29 @@ public class JavacParser implements Parser {
case RETURN: {
nextToken();
JCExpression result = token.kind == SEMI ? null : parseExpression();
JCReturn t = to(F.at(pos).Return(result));
accept(SEMI);
JCReturn t = toP(F.at(pos).Return(result));
return t;
}
case THROW: {
nextToken();
JCExpression exc = parseExpression();
JCThrow t = to(F.at(pos).Throw(exc));
accept(SEMI);
JCThrow t = toP(F.at(pos).Throw(exc));
return t;
}
case BREAK: {
nextToken();
Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
JCBreak t = to(F.at(pos).Break(label));
accept(SEMI);
JCBreak t = toP(F.at(pos).Break(label));
return t;
}
case CONTINUE: {
nextToken();
Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
JCContinue t = to(F.at(pos).Continue(label));
accept(SEMI);
JCContinue t = toP(F.at(pos).Continue(label));
return t;
}
case SEMI:
@ -2593,8 +2601,8 @@ public class JavacParser implements Parser {
nextToken();
message = parseExpression();
}
JCAssert t = to(F.at(pos).Assert(assertion, message));
accept(SEMI);
JCAssert t = toP(F.at(pos).Assert(assertion, message));
return t;
}
/* else fall through to default case */
@ -2609,8 +2617,9 @@ public class JavacParser implements Parser {
return F.at(pos).Labelled(prevToken.name(), stat);
} else {
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
expr = checkExprStat(expr);
accept(SEMI);
JCExpressionStatement stat = toP(F.at(pos).Exec(expr));
return stat;
}
}
@ -3513,8 +3522,8 @@ public class JavacParser implements Parser {
List<JCTree> defs =
variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
new ListBuffer<JCTree>()).toList();
storeEnd(defs.last(), token.endPos);
accept(SEMI);
storeEnd(defs.last(), S.prevToken().endPos);
return defs;
} else {
pos = token.pos;

View File

@ -67,7 +67,6 @@ Actual: <A HREF="{@docRoot}p1/package-summary.html#package_description">package
Actual: <A HREF="{@docRoot}/p1/package-summary.html#package_description">package description</A> {&#064;docRoot}/p1/package-summary.html#package_description <br>
Expect: <A HREF="../p1/package-summary.html#package_description">../p1/package-summary.html#package description</a>
<p>
</BODY>
</HTML>

View File

@ -9,7 +9,6 @@ with examples of a wide variety of Java language constructs: packages,
subclasses, subinterfaces, nested classes, nested interfaces,
inheriting from other packages, constructors, fields,
methods, and so forth.
<p>
</body>
</html>

View File

@ -9,7 +9,6 @@ with examples of a wide variety of Java language constructs: packages,
subclasses, subinterfaces, nested classes, nested interfaces,
inheriting from other packages, constructors, fields,
methods, and so forth.
<p>
</body>
</html>

View File

@ -0,0 +1,15 @@
/* @test /nodynamiccopyright/
* @bug 8037385
* @summary Must not allow static interface method invocation in legacy code
* @compile -source 8 -Xlint:-options StaticInvoke.java
* @compile/fail/ref=StaticInvoke7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvoke.java
* @compile/fail/ref=StaticInvoke6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvoke.java
*/
import java.util.stream.Stream;
class StaticInvoke {
void test() {
Stream.empty();
java.util.stream.Stream.empty();
}
}

View File

@ -0,0 +1,3 @@
StaticInvoke.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
StaticInvoke.java:13:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
2 errors

View File

@ -0,0 +1,3 @@
StaticInvoke.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
StaticInvoke.java:13:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
2 errors

View File

@ -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.
*/
/**
* @test
* @bug 8044546
* @summary Crash on faulty reduce/lambda
* @compile CrashImplicitLambdaTest.java
*/
abstract class CrashImplicitLambdaTest {
boolean foo() {
return bar(true, a -> {});
}
abstract <T1> T1 bar(T1 t1, S<T1> s);
interface S<S1> {
void baz(S1 s1);
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.
*/
/**
* @test
* @bug 8044546
* @summary Crash on faulty reduce/lambda
* @compile NestedInvocationsTest.java
*/
class NestedInvocationsTest<T> {
boolean foo(I<T> i) {
return baz(zas(i));
}
<U> J<U, Boolean> zas(I<U> i) {
return null;
}
<R> R baz(J<T, R> j) {
return null;
}
interface I<I1> {}
interface J<J1, J2> {}
}

View File

@ -0,0 +1,35 @@
/*
* 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.
*/
/*
* @test
* @bug 8034147
* @summary javac crashes with a NullPointerException during bounds checking
* @compile T8034147.java
*/
class T8034147 {
static class One<X extends Two<? super X>> {}
static class Two<Y extends Three<? extends Y>> implements Three<Y> {}
interface Three<Z> {}
}

View File

@ -0,0 +1,70 @@
/*
* 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.
*/
/*
* @test
* @bug 8046060
* @summary Different results of floating point multiplication for lambda code block
*/
strictfp
public class LambdaTestStrictFP {
static double fld = eval(() -> {
double x = Double.longBitsToDouble(0x1e7ee00000000000L);
double y = Double.longBitsToDouble(0x2180101010101010L);
return x * y;
});
public static void main(String args[]) {
double result = eval(() -> {
double x = Double.longBitsToDouble(0x1e7ee00000000000L);
double y = Double.longBitsToDouble(0x2180101010101010L);
return x * y;
});
{
double x = Double.longBitsToDouble(0x1e7ee00000000000L);
double y = Double.longBitsToDouble(0x2180101010101010L);
double z = x * y;
check(z, result, "method");
check(z, fld, "field");
}
}
private static void check(double expected, double got, String where) {
if (got != expected) {
throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected);
}
}
private static double eval(Face arg) {
return arg.m();
}
private interface Face {
double m();
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.
*/
/*
* @test
* @bug 8046060
* @summary Different results of floating point multiplication for lambda code block
*/
import java.io.*;
import java.net.URL;
import com.sun.tools.classfile.*;
import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
public class LambdaTestStrictFPFlag {
public static void main(String[] args) throws Exception {
new LambdaTestStrictFPFlag().run();
}
void run() throws Exception {
ClassFile cf = getClassFile("LambdaTestStrictFPFlag$Test.class");
ConstantPool cp = cf.constant_pool;
boolean found = false;
for (Method meth: cf.methods) {
if (meth.getName(cp).startsWith("lambda$")) {
if ((meth.access_flags.flags & ACC_STRICT) == 0) {
throw new Exception("strict flag missing from lambda");
}
found = true;
}
}
if (!found) {
throw new Exception("did not find lambda method");
}
}
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
URL url = getClass().getResource(name);
InputStream in = url.openStream();
try {
return ClassFile.read(in);
} finally {
in.close();
}
}
class Test {
strictfp void test() {
Face itf = () -> { };
}
}
interface Face {
void m();
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.
*/
/*
* @test
* @bug 8046060
* @summary Different results of floating point multiplication for lambda code block
*/
public class LambdaTestStrictFPMethod {
public static void main(String args[]) {
new LambdaTestStrictFPMethod().test();
}
strictfp void test() {
double result = eval(() -> {
double x = Double.longBitsToDouble(0x1e7ee00000000000L);
double y = Double.longBitsToDouble(0x2180101010101010L);
return x * y;
});
{
double x = Double.longBitsToDouble(0x1e7ee00000000000L);
double y = Double.longBitsToDouble(0x2180101010101010L);
double z = x * y;
check(z, result, "method");
}
}
strictfp void check(double expected, double got, String where) {
if (got != expected) {
throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected);
}
}
static double eval(Face arg) {
return arg.m();
}
interface Face {
double m();
}
}

View File

@ -0,0 +1,24 @@
/*
* @test /nodynamiccopyright/
* @bug 8038182
* @summary javac crash with FunctionDescriptorLookupError for invalid functional interface
* @compile/fail/ref=CrashFunctionDescriptorExceptionTest.out -XDrawDiagnostics CrashFunctionDescriptorExceptionTest.java
*/
class CrashFunctionDescriptorExceptionTest {
@SuppressWarnings("unchecked")
void m () {
bar((B b) -> {});
}
<E extends A<E>> void bar(I<E> i) {}
class A<E> {}
class B<E> extends A<E> {}
interface I<E extends A<E>> {
void foo(E e);
}
}

View File

@ -0,0 +1,2 @@
CrashFunctionDescriptorExceptionTest.java:12:13: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: CrashFunctionDescriptorExceptionTest.I<CrashFunctionDescriptorExceptionTest.B>)
1 error

View File

@ -0,0 +1,33 @@
/*
* @test /nodynamiccopyright/
* @bug 8042759
* @summary Lambda returning implicitly-typed lambdas considered pertinent to applicability
* @compile/fail/ref=ImplicitLambdaConsideredForApplicabilityTest.out -XDrawDiagnostics ImplicitLambdaConsideredForApplicabilityTest.java
*/
abstract class ImplicitLambdaConsideredForApplicabilityTest {
interface A {
B m(int a, int b);
}
interface C {
String m(int a, int b);
}
interface B {
int m(int c);
}
abstract void foo(A a);
abstract void foo(C c);
void bar() {
foo((int a, int b) -> {
if(a < b)
return c -> 0;
else
return c -> 0;
});
}
}

View File

@ -0,0 +1,2 @@
ImplicitLambdaConsideredForApplicabilityTest.java:26:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(ImplicitLambdaConsideredForApplicabilityTest.A), ImplicitLambdaConsideredForApplicabilityTest, kindname.method, foo(ImplicitLambdaConsideredForApplicabilityTest.C), ImplicitLambdaConsideredForApplicabilityTest
1 error

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2010, 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.
*/
/*
* @test
* @bug 8041648
* @summary Verify that end positions are sane if semicolons are missing.
* @run main MissingSemicolonTest MissingSemicolonTest.java
*/
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.util.*;
import javax.tools.*;
import com.sun.source.tree.*;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.util.*;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.parser.Scanner;
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
public class MissingSemicolonTest {
public static void main(String... args) {
String testSrc = System.getProperty("test.src");
File baseDir = new File(testSrc);
boolean ok = new MissingSemicolonTest().run(baseDir, args);
if (!ok) {
throw new Error("failed");
}
}
boolean run(File baseDir, String... args) {
if (args.length == 0) {
throw new IllegalStateException("Needs input files.");
}
for (String arg : args) {
File file = new File(baseDir, arg);
if (file.exists())
test(file);
else
error("File not found: " + file);
}
System.err.println(fileCount + " files read");
if (errors > 0)
System.err.println(errors + " errors");
return errors == 0;
}
void test(File file) {
if (file.isFile() && file.getName().endsWith(".java")) {
try {
fileCount++;
String content = new String(Files.readAllBytes(file.toPath()));
List<int[]> spans = gatherTreeSpans(file, content);
int nextSemicolon = -1;
//remove semicolons, one at a time, and verify the positions are still meaningful:
while ((nextSemicolon = content.indexOf(';', nextSemicolon + 1)) != (-1)) {
String updatedContent =
content.substring(0, nextSemicolon) +
" " +
content.substring(nextSemicolon + 1);
verifyTreeSpans(file, spans, updatedContent, nextSemicolon);
}
} catch (IOException e) {
error("Error reading " + file + ": " + e);
}
}
}
public List<int[]> gatherTreeSpans(File file, String content) throws IOException {
JCCompilationUnit unit = read(file.toURI(), content);
List<int[]> spans = new ArrayList<>();
new TreePathScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void p) {
if (tree != null) {
int start = ((JCTree) tree).getStartPosition();
int end = ((JCTree) tree).getEndPosition(unit.endPositions);
spans.add(new int[] {start, end});
}
return super.scan(tree, p);
}
}.scan(unit, null);
return spans;
}
public void verifyTreeSpans(File file, List<int[]> spans,
String updatedContent, int semicolon) throws IOException {
JCCompilationUnit updated = read(file.toURI(), updatedContent);
Iterator<int[]> nextSpan = spans.iterator();
new TreePathScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void p) {
if (tree != null) {
int start = ((JCTree) tree).getStartPosition();
int end = ((JCTree) tree).getEndPosition(updated.endPositions);
if (tree.getKind() != Kind.ERRONEOUS) {
int[] expected = nextSpan.next();
int expectedEnd = expected[1];
if (expectedEnd == semicolon + 1) {
Scanner scanner = scannerFactory.newScanner(updatedContent, true);
scanner.nextToken();
while (scanner.token().pos < expectedEnd)
scanner.nextToken();
expectedEnd = scanner.token().pos;
}
if (expected[0] != start || expectedEnd != end) {
error(updatedContent + "; semicolon: " + semicolon + "; expected: " +
expected[0] + "-" + expectedEnd + "; found=" + start + "-" + end +
";" + tree);
}
}
}
return super.scan(tree, p);
}
}.scan(updated, null);
}
DiagnosticListener<JavaFileObject> devNull = (d) -> {};
JavacTool tool = JavacTool.create();
StandardJavaFileManager fm = tool.getStandardFileManager(devNull, null, null);
ScannerFactory scannerFactory = ScannerFactory.instance(new Context());
/**
* Read a file.
* @param file the file to be read
* @return the tree for the content of the file
* @throws IOException if any IO errors occur
* @throws MissingSemicolonTest.ParseException if any errors occur while parsing the file
*/
JCCompilationUnit read(URI uri, String content) throws IOException {
JavacTool tool = JavacTool.create();
JavacTask task = tool.getTask(null, fm, devNull, Collections.<String>emptyList(), null,
Arrays.<JavaFileObject>asList(new JavaSource(uri, content)));
Iterable<? extends CompilationUnitTree> trees = task.parse();
Iterator<? extends CompilationUnitTree> iter = trees.iterator();
if (!iter.hasNext())
throw new Error("no trees found");
JCCompilationUnit t = (JCCompilationUnit) iter.next();
if (iter.hasNext())
throw new Error("too many trees found");
return t;
}
class JavaSource extends SimpleJavaFileObject {
private final String content;
public JavaSource(URI uri, String content) {
super(uri, JavaFileObject.Kind.SOURCE);
this.content = content;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return content;
}
}
/**
* Report an error. When the program is complete, the program will either
* exit or throw an Error if any errors have been reported.
* @param msg the error message
*/
void error(String msg) {
System.err.println(msg);
errors++;
}
/** Number of files that have been analyzed. */
int fileCount;
/** Number of errors reported. */
int errors;
}
class TestCase {
String str1;
String str2;
public TestCase() {
super();
super.hashCode();
}
public TestCase(String str1, String str2) {
super();
this.str1 = str1;
this.str2 = str2;
assert true;
}
void newClass() {
new String();
new String();
}
void localVars() {
String str1 = "";
String str2;
String str3;
final String str4;
}
void throwsException() {
throw new IllegalStateException();
}
int returnWithExpression() {
return 1;
}
void returnWithoutExpression() {
return ;
}
void doWhileBreakContinue() {
do {
if (true)
break;
if (false)
continue;
} while(true);
}
void labelled() {
LABEL: doWhileBreakContinue();
}
}

View File

@ -38,15 +38,17 @@ public class Test extends Doclet {
}
void run() throws Exception {
test("<html><body>ABC XYZ</body></html>");
test("<html><body>ABC XYZ</BODY></html>");
test("<html><BODY>ABC XYZ</body></html>");
test("<html><BODY>ABC XYZ</BODY></html>");
test("<html><BoDy>ABC XYZ</bOdY></html>");
test("<html> ABC XYZ</bOdY></html>", "Body tag missing from HTML");
test("<html><body>ABC XYZ </html>", "Close body tag missing from HTML");
test("<html> ABC XYZ </html>", "Body tag missing from HTML");
test("<html><body>ABC" + bigText(8192, 40) + "XYZ</body></html>");
String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
+ "\"http://www.w3.org/TR/html4/loose.dtd\">";
test(docType+"<html><body>ABC XYZ</body></html>");
test(docType+"<html><body>ABC XYZ</BODY></html>");
test(docType+"<html><BODY>ABC XYZ</body></html>");
test(docType+"<html><BODY>ABC XYZ</BODY></html>");
test(docType+"<html><BoDy>ABC XYZ</bOdY></html>");
test(docType+"<html> ABC XYZ</bOdY></html>", "Body tag missing from HTML");
test(docType+"<html><body>ABC XYZ </html>", "Close body tag missing from HTML");
test(docType+"<html> ABC XYZ </html>", "Body tag missing from HTML");
test(docType+"<html><body>ABC" + bigText(8192, 40) + "XYZ</body></html>");
if (errors > 0)
throw new Exception(errors + " errors occurred");