mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 02:54:35 +02:00
8064464: regression with type inference of conditional expression
Bad classification of conditional leads to spurious error Reviewed-by: jlahoda
This commit is contained in:
parent
732c7c5e28
commit
ed9c1bb743
7 changed files with 52 additions and 13 deletions
|
@ -1429,21 +1429,28 @@ public class Attr extends JCTree.Visitor {
|
|||
case APPLY:
|
||||
JCMethodInvocation speculativeMethodTree =
|
||||
(JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
|
||||
Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
|
||||
return types.unboxedTypeOrType(owntype).isPrimitive();
|
||||
Symbol msym = TreeInfo.symbol(speculativeMethodTree.meth);
|
||||
Type receiverType = speculativeMethodTree.meth.hasTag(IDENT) ?
|
||||
env.enclClass.type :
|
||||
((JCFieldAccess)speculativeMethodTree.meth).selected.type;
|
||||
Type owntype = types.memberType(receiverType, msym).getReturnType();
|
||||
return primitiveOrBoxed(owntype);
|
||||
case NEWCLASS:
|
||||
JCExpression className =
|
||||
removeClassParams.translate(((JCNewClass)tree).clazz);
|
||||
JCExpression speculativeNewClassTree =
|
||||
(JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
|
||||
return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
|
||||
return primitiveOrBoxed(speculativeNewClassTree.type);
|
||||
default:
|
||||
Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
|
||||
speculativeType = types.unboxedTypeOrType(speculativeType);
|
||||
return speculativeType.isPrimitive();
|
||||
return primitiveOrBoxed(speculativeType);
|
||||
}
|
||||
}
|
||||
//where
|
||||
boolean primitiveOrBoxed(Type t) {
|
||||
return (!t.hasTag(TYPEVAR) && types.unboxedTypeOrType(t).isPrimitive());
|
||||
}
|
||||
|
||||
TreeTranslator removeClassParams = new TreeTranslator() {
|
||||
@Override
|
||||
public void visitTypeApply(JCTypeApply tree) {
|
||||
|
|
|
@ -1213,7 +1213,10 @@ public class DeferredAttr extends JCTree.Visitor {
|
|||
return;
|
||||
}
|
||||
scan(tree.falsepart);
|
||||
result = reduce(ArgumentExpressionKind.PRIMITIVE);
|
||||
result = reduce(ArgumentExpressionKind.PRIMITIVE).isPrimitive() ?
|
||||
ArgumentExpressionKind.PRIMITIVE :
|
||||
ArgumentExpressionKind.POLY;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 4974927
|
||||
* @bug 4974927 8064464
|
||||
* @summary The compiler was allowing void types in its parsing of conditional expressions.
|
||||
* @author tball
|
||||
*
|
||||
* @compile/fail/ref=ConditionalWithVoid.out -XDrawDiagnostics ConditionalWithVoid.java
|
||||
*/
|
||||
public class ConditionalWithVoid {
|
||||
public int test(Object o) {
|
||||
// Should fail to compile since Object.wait() has a void return type.
|
||||
public void test(Object o) {
|
||||
// Should fail to compile since Object.wait() has a void return type. Poly case.
|
||||
System.out.println(o instanceof String ? o.hashCode() : o.wait());
|
||||
// Should fail to compile since Object.wait() has a void return type. Standalone case.
|
||||
(o instanceof String ? o.hashCode() : o.wait()).toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
ConditionalWithVoid.java:12:48: compiler.err.neither.conditional.subtype: java.lang.Integer, void
|
||||
1 error
|
||||
ConditionalWithVoid.java:12:71: compiler.err.void.not.allowed.here
|
||||
ConditionalWithVoid.java:14:30: compiler.err.neither.conditional.subtype: java.lang.Integer, void
|
||||
2 errors
|
||||
|
|
23
langtools/test/tools/javac/conditional/8064464/T8064464.java
Normal file
23
langtools/test/tools/javac/conditional/8064464/T8064464.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8064464
|
||||
* @summary regression with type inference of conditional expression
|
||||
* @compile/fail/ref=T8064464.out -XDrawDiagnostics T8064464.java
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class T8064464 {
|
||||
|
||||
String f(Object o) { return null; }
|
||||
Integer f(int i) { return null; }
|
||||
|
||||
<X extends Integer> X id() { return null; }
|
||||
|
||||
void m(List<Integer> lx) {
|
||||
Integer i1 = f(!lx.isEmpty() ? 0 : lx.get(0)); //ok --> f(int)
|
||||
Integer i2 = f(!lx.isEmpty() ? lx.get(0) : 0); //ok --> f(int)
|
||||
f(!lx.isEmpty() ? id() : 0); // ambiguous
|
||||
f(!lx.isEmpty() ? 0 : id()); // ambiguous
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
T8064464.java:20:5: compiler.err.ref.ambiguous: f, kindname.method, f(java.lang.Object), T8064464, kindname.method, f(int), T8064464
|
||||
T8064464.java:21:5: compiler.err.ref.ambiguous: f, kindname.method, f(java.lang.Object), T8064464, kindname.method, f(int), T8064464
|
||||
2 errors
|
|
@ -24,9 +24,9 @@
|
|||
// key: compiler.err.neither.conditional.subtype
|
||||
|
||||
class NeitherConditionalSubtype {
|
||||
public int test(Object o) {
|
||||
public int test(boolean cond, Object o) {
|
||||
// Should fail to compile since Object.wait() has a void return type.
|
||||
System.out.println(o instanceof String ? o.hashCode() : o.wait());
|
||||
(o instanceof String ? o.hashCode() : o.wait()).toString();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue