* 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:
Minero Aoki 2008-08-19 07:19:15 +00:00
parent 8c51d5d1a7
commit 5f8ff3aefc
2 changed files with 25 additions and 4 deletions

View File

@ -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

View File

@ -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)) {