mirror of https://github.com/aamine/cbc
* net/loveruby/cflat/compiler/TypeChecker.java: allow safe implicit integer cast like "char c = 0" adhocly.
git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3962 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
8c51d5d1a7
commit
5f8ff3aefc
|
@ -1,3 +1,8 @@
|
||||||
|
Thu May 8 22:00:04 2008 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
|
* net/loveruby/cflat/compiler/TypeChecker.java: allow safe
|
||||||
|
implicit integer cast like "char c = 0" adhocly.
|
||||||
|
|
||||||
Thu May 8 21:39:49 2008 Minero Aoki <aamine@loveruby.net>
|
Thu May 8 21:39:49 2008 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
* net/loveruby/cflat/type/IntegerType.java: new method
|
* net/loveruby/cflat/type/IntegerType.java: new method
|
||||||
|
|
|
@ -164,7 +164,8 @@ class TypeChecker extends Visitor {
|
||||||
Type l = integralPromotion(node.lhs().type());
|
Type l = integralPromotion(node.lhs().type());
|
||||||
Type r = integralPromotion(node.rhs().type());
|
Type r = integralPromotion(node.rhs().type());
|
||||||
Type opType = usualArithmeticConversion(l, r);
|
Type opType = usualArithmeticConversion(l, r);
|
||||||
if (! opType.isCompatible(l)) {
|
if (! opType.isCompatible(l)
|
||||||
|
&& ! isSafeIntegerCast(node.rhs(), opType)) {
|
||||||
warn(node, "incompatible implicit cast from "
|
warn(node, "incompatible implicit cast from "
|
||||||
+ opType + " to " + l);
|
+ opType + " to " + l);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +175,20 @@ class TypeChecker extends Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** allow safe implicit cast from integer literal like:
|
||||||
|
*
|
||||||
|
* char c = 0;
|
||||||
|
*
|
||||||
|
* "0" has a type integer, but we can cast (int)0 to (char)0 safely.
|
||||||
|
*/
|
||||||
|
protected boolean isSafeIntegerCast(Node node, Type type) {
|
||||||
|
if (! type.isInteger()) return false;
|
||||||
|
IntegerType t = (IntegerType)type;
|
||||||
|
if (! (node instanceof IntegerLiteralNode)) return false;
|
||||||
|
IntegerLiteralNode n = (IntegerLiteralNode)node;
|
||||||
|
return t.isInDomain(n.value());
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean checkLHS(ExprNode lhs) {
|
protected boolean checkLHS(ExprNode lhs) {
|
||||||
if (lhs.isParameter()) {
|
if (lhs.isParameter()) {
|
||||||
// parameter is always assignable.
|
// parameter is always assignable.
|
||||||
|
@ -421,7 +436,8 @@ class TypeChecker extends Visitor {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
else if (expr.type().isCastableTo(targetType)) {
|
else if (expr.type().isCastableTo(targetType)) {
|
||||||
if (! expr.type().isCompatible(targetType)) {
|
if (! expr.type().isCompatible(targetType)
|
||||||
|
&& ! isSafeIntegerCast(expr, targetType)) {
|
||||||
warn(expr, "incompatible implicit cast from "
|
warn(expr, "incompatible implicit cast from "
|
||||||
+ expr.type() + " to " + targetType);
|
+ expr.type() + " to " + targetType);
|
||||||
}
|
}
|
||||||
|
@ -457,8 +473,8 @@ class TypeChecker extends Visitor {
|
||||||
Type u_int = typeTable.unsignedInt();
|
Type u_int = typeTable.unsignedInt();
|
||||||
Type s_long = typeTable.signedLong();
|
Type s_long = typeTable.signedLong();
|
||||||
Type u_long = typeTable.unsignedLong();
|
Type u_long = typeTable.unsignedLong();
|
||||||
if ( (l.isSameType(u_int) && r.isSameType(s_long))
|
if ( (l.isSameType(u_int) && r.isSameType(s_long))
|
||||||
|| (r.isSameType(u_int) && l.isSameType(s_long))) {
|
|| (r.isSameType(u_int) && l.isSameType(s_long))) {
|
||||||
return u_long;
|
return u_long;
|
||||||
}
|
}
|
||||||
else if (l.isSameType(u_long) || r.isSameType(u_long)) {
|
else if (l.isSameType(u_long) || r.isSameType(u_long)) {
|
||||||
|
|
Loading…
Reference in New Issue