mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-04 02:35:33 +00:00
8138840: NPE when compiling bitwise operations with illegal operand types
8139243: compiler crashes with exception on sum operation of String var and void method call result 8139249: Compiler crashes on unary bitwise complement with non-integral operand Certain binary operator checks are accepting more operands than required. Reviewed-by: jlahoda
This commit is contained in:
parent
119988f54a
commit
4d32c48daf
@ -142,6 +142,10 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isIntegral() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return false;
|
||||
}
|
||||
@ -696,6 +700,20 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
|
||||
return tag != BOOLEAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIntegral() {
|
||||
switch (tag) {
|
||||
case CHAR:
|
||||
case BYTE:
|
||||
case SHORT:
|
||||
case INT:
|
||||
case LONG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrimitive() {
|
||||
return true;
|
||||
|
||||
@ -404,13 +404,20 @@ public class Operators {
|
||||
*/
|
||||
class UnaryNumericOperator extends UnaryOperatorHelper {
|
||||
|
||||
Predicate<Type> numericTest;
|
||||
|
||||
UnaryNumericOperator(Tag tag) {
|
||||
this(tag, Type::isNumeric);
|
||||
}
|
||||
|
||||
UnaryNumericOperator(Tag tag, Predicate<Type> numericTest) {
|
||||
super(tag);
|
||||
this.numericTest = numericTest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Type type) {
|
||||
return unaryPromotion(type).isNumeric();
|
||||
return numericTest.test(unaryPromotion(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -462,8 +469,15 @@ public class Operators {
|
||||
*/
|
||||
class BinaryNumericOperator extends BinaryOperatorHelper {
|
||||
|
||||
Predicate<Type> numericTest;
|
||||
|
||||
BinaryNumericOperator(Tag tag) {
|
||||
this(tag, Type::isNumeric);
|
||||
}
|
||||
|
||||
BinaryNumericOperator(Tag tag, Predicate<Type> numericTest) {
|
||||
super(tag);
|
||||
this.numericTest = numericTest;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -474,7 +488,8 @@ public class Operators {
|
||||
|
||||
@Override
|
||||
public boolean test(Type arg1, Type arg2) {
|
||||
return unaryPromotion(arg1).isNumeric() && unaryPromotion(arg2).isNumeric();
|
||||
return numericTest.test(unaryPromotion(arg1)) &&
|
||||
numericTest.test(unaryPromotion(arg2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,20 +533,22 @@ public class Operators {
|
||||
|
||||
@Override
|
||||
public boolean test(Type arg1, Type arg2) {
|
||||
return types.isSameType(arg1, syms.stringType) ||
|
||||
boolean hasStringOp = types.isSameType(arg1, syms.stringType) ||
|
||||
types.isSameType(arg2, syms.stringType);
|
||||
boolean hasVoidOp = arg1.hasTag(TypeTag.VOID) || arg2.hasTag(TypeTag.VOID);
|
||||
return hasStringOp && !hasVoidOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine applies following mappings:
|
||||
* - if input type is primitive, apply numeric promotion
|
||||
* - if input type is either 'null' or 'String' leave it untouched
|
||||
* - if input type is either 'void', 'null' or 'String' leave it untouched
|
||||
* - otherwise return 'Object'
|
||||
*/
|
||||
private Type stringPromotion(Type t) {
|
||||
if (t.isPrimitive()) {
|
||||
return unaryPromotion(t);
|
||||
} else if (t.hasTag(TypeTag.BOT) ||
|
||||
} else if (t.hasTag(TypeTag.VOID) || t.hasTag(TypeTag.BOT) ||
|
||||
types.isSameType(t, syms.stringType)) {
|
||||
return t;
|
||||
} else if (t.hasTag(TypeTag.TYPEVAR)) {
|
||||
@ -640,7 +657,7 @@ public class Operators {
|
||||
.addUnaryOperator(FLOAT, FLOAT, fneg)
|
||||
.addUnaryOperator(LONG, LONG, lneg)
|
||||
.addUnaryOperator(INT, INT, ineg),
|
||||
new UnaryNumericOperator(Tag.COMPL)
|
||||
new UnaryNumericOperator(Tag.COMPL, Type::isIntegral)
|
||||
.addUnaryOperator(LONG, LONG, lxor)
|
||||
.addUnaryOperator(INT, INT, ixor),
|
||||
new UnaryPrefixPostfixOperator(Tag.POSTINC)
|
||||
@ -713,17 +730,17 @@ public class Operators {
|
||||
.addBinaryOperator(INT, INT, INT, imod),
|
||||
new BinaryBooleanOperator(Tag.BITAND)
|
||||
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, iand),
|
||||
new BinaryNumericOperator(Tag.BITAND)
|
||||
new BinaryNumericOperator(Tag.BITAND, Type::isIntegral)
|
||||
.addBinaryOperator(LONG, LONG, LONG, land)
|
||||
.addBinaryOperator(INT, INT, INT, iand),
|
||||
new BinaryBooleanOperator(Tag.BITOR)
|
||||
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ior),
|
||||
new BinaryNumericOperator(Tag.BITOR)
|
||||
new BinaryNumericOperator(Tag.BITOR, Type::isIntegral)
|
||||
.addBinaryOperator(LONG, LONG, LONG, lor)
|
||||
.addBinaryOperator(INT, INT, INT, ior),
|
||||
new BinaryBooleanOperator(Tag.BITXOR)
|
||||
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ixor),
|
||||
new BinaryNumericOperator(Tag.BITXOR)
|
||||
new BinaryNumericOperator(Tag.BITXOR, Type::isIntegral)
|
||||
.addBinaryOperator(LONG, LONG, LONG, lxor)
|
||||
.addBinaryOperator(INT, INT, INT, ixor),
|
||||
new BinaryShiftOperator(Tag.SL)
|
||||
|
||||
12
langtools/test/tools/javac/8138840/T8138840.java
Normal file
12
langtools/test/tools/javac/8138840/T8138840.java
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8138840 8139243 8139249
|
||||
* @summary Compiler crashes when compiling bitwise operations with illegal operand types
|
||||
* @compile/fail/ref=T8138840.out -XDrawDiagnostics T8138840.java
|
||||
*/
|
||||
|
||||
class T8138840 {
|
||||
void test(int x, double d) {
|
||||
Object o = x & d;
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/8138840/T8138840.out
Normal file
2
langtools/test/tools/javac/8138840/T8138840.out
Normal file
@ -0,0 +1,2 @@
|
||||
T8138840.java:10:22: compiler.err.operator.cant.be.applied.1: &, int, double
|
||||
1 error
|
||||
16
langtools/test/tools/javac/8138840/T8139243.java
Normal file
16
langtools/test/tools/javac/8138840/T8139243.java
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8138840 8139243 8139249
|
||||
* @summary Compiler crashes when compiling bitwise operations with illegal operand types
|
||||
* 'void' is erroneously accepted as a possible operand for string concatenation
|
||||
* @compile/fail/ref=T8139243.out -XDrawDiagnostics T8139243.java
|
||||
*/
|
||||
|
||||
class T8139243 {
|
||||
|
||||
void test(String s) {
|
||||
s += m(); // compile time error
|
||||
}
|
||||
|
||||
void m() { }
|
||||
}
|
||||
2
langtools/test/tools/javac/8138840/T8139243.out
Normal file
2
langtools/test/tools/javac/8138840/T8139243.out
Normal file
@ -0,0 +1,2 @@
|
||||
T8139243.java:12:11: compiler.err.operator.cant.be.applied.1: +, java.lang.String, void
|
||||
1 error
|
||||
13
langtools/test/tools/javac/8138840/T8139249.java
Normal file
13
langtools/test/tools/javac/8138840/T8139249.java
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8138840 8139243 8139249
|
||||
* @summary Compiler crashes when compiling bitwise operations with illegal operand types
|
||||
* Unary operator erroneously applied to non-integral type operand
|
||||
* @compile/fail/ref=T8139249.out -XDrawDiagnostics T8139249.java
|
||||
*/
|
||||
|
||||
class T8139249 {
|
||||
void test(float f2) {
|
||||
float f1 = ~f2;
|
||||
}
|
||||
}
|
||||
2
langtools/test/tools/javac/8138840/T8139249.out
Normal file
2
langtools/test/tools/javac/8138840/T8139249.out
Normal file
@ -0,0 +1,2 @@
|
||||
T8139249.java:11:20: compiler.err.operator.cant.be.applied: ~, float
|
||||
1 error
|
||||
Loading…
x
Reference in New Issue
Block a user