Fixed 'IDEA-128594: Variable type incorrectly set to boolean'

master
Stiver 10 years ago
parent 70bf7f3f69
commit de249340fc
  1. 37
      src/de/fernflower/modules/decompiler/exps/FunctionExprent.java
  2. 25
      src/de/fernflower/struct/gen/VarType.java

@ -369,40 +369,45 @@ public class FunctionExprent extends Exprent {
case FUNCTION_AND: case FUNCTION_AND:
case FUNCTION_OR: case FUNCTION_OR:
case FUNCTION_XOR: case FUNCTION_XOR:
if(type1.type == CodeConstants.TYPE_BOOLEAN && {
((type1.convinfo & VarType.FALSEBOOLEAN) != 0 || type2.type != CodeConstants.TYPE_BOOLEAN)) { boolean param1_false_boolean = type1.isFalseBoolean() || (param1.type == Exprent.EXPRENT_CONST && !((ConstExprent)param1).hasBooleanValue());
boolean param2_false_boolean = type1.isFalseBoolean() || (param2.type == Exprent.EXPRENT_CONST && !((ConstExprent)param2).hasBooleanValue());
if(param1_false_boolean || param2_false_boolean) {
if(type1.type == CodeConstants.TYPE_BOOLEAN) {
result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR);
} }
if(type2.type == CodeConstants.TYPE_BOOLEAN &&
((type2.convinfo & VarType.FALSEBOOLEAN) != 0 || type1.type != CodeConstants.TYPE_BOOLEAN)) { if(type2.type == CodeConstants.TYPE_BOOLEAN) {
result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR); result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR);
} }
}
}
break; break;
case FUNCTION_EQ: case FUNCTION_EQ:
case FUNCTION_NE: case FUNCTION_NE:
{
if(type1.type == CodeConstants.TYPE_BOOLEAN) { if(type1.type == CodeConstants.TYPE_BOOLEAN) {
if(type2.isStrictSuperset(type1)) { if(type2.isStrictSuperset(type1)) {
result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR);
} else {
if(param1.type == Exprent.EXPRENT_CONST && !((ConstExprent)param1).hasBooleanValue()) { } else { // both are booleans
if(param2.type != Exprent.EXPRENT_CONST || !((ConstExprent)param2).hasBooleanValue()) { // variable or not boolean constant
boolean param1_false_boolean = type1.isFalseBoolean() || (param1.type == Exprent.EXPRENT_CONST && !((ConstExprent)param1).hasBooleanValue());
boolean param2_false_boolean = type1.isFalseBoolean() || (param2.type == Exprent.EXPRENT_CONST && !((ConstExprent)param2).hasBooleanValue());
if(param1_false_boolean || param2_false_boolean) {
result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR);
} result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR);
}
} }
} }
if(type2.type == CodeConstants.TYPE_BOOLEAN) { } else if(type2.type == CodeConstants.TYPE_BOOLEAN) {
if(type1.isStrictSuperset(type2)) { if(type1.isStrictSuperset(type2)) {
result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR); result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR);
} else {
if(param2.type == Exprent.EXPRENT_CONST && !((ConstExprent)param2).hasBooleanValue()) {
if(param1.type != Exprent.EXPRENT_CONST || !((ConstExprent)param1).hasBooleanValue()) { // variable or not boolean constant
result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR);
}
} }
} }
} }

@ -115,6 +115,10 @@ public class VarType { // TODO: optimize switch
return v; return v;
} }
public boolean isFalseBoolean() {
return (convinfo & VarType.FALSEBOOLEAN) != 0;
}
public boolean isSuperset(VarType val) { public boolean isSuperset(VarType val) {
return this.equals(val) || this.isStrictSuperset(val); return this.equals(val) || this.isStrictSuperset(val);
@ -165,6 +169,10 @@ public class VarType { // TODO: optimize switch
// type1 and type2 must not be null // type1 and type2 must not be null
public static VarType getCommonMinType(VarType type1, VarType type2) { public static VarType getCommonMinType(VarType type1, VarType type2) {
if(type1.type == CodeConstants.TYPE_BOOLEAN && type2.type == CodeConstants.TYPE_BOOLEAN) { // special case booleans
return type1.isFalseBoolean() ? type2 : type1;
}
if(type1.isSuperset(type2)) { if(type1.isSuperset(type2)) {
return type2; return type2;
} else if(type2.isSuperset(type1)) { } else if(type2.isSuperset(type1)) {
@ -189,6 +197,10 @@ public class VarType { // TODO: optimize switch
// type1 and type2 must not be null // type1 and type2 must not be null
public static VarType getCommonSupertype(VarType type1, VarType type2) { public static VarType getCommonSupertype(VarType type1, VarType type2) {
if(type1.type == CodeConstants.TYPE_BOOLEAN && type2.type == CodeConstants.TYPE_BOOLEAN) { // special case booleans
return type1.isFalseBoolean() ? type1 : type2;
}
if(type1.isSuperset(type2)) { if(type1.isSuperset(type2)) {
return type1; return type1;
} else if(type2.isSuperset(type1)) { } else if(type2.isSuperset(type1)) {
@ -232,12 +244,17 @@ public class VarType { // TODO: optimize switch
} }
public boolean equals(Object o) { public boolean equals(Object o) {
if(o == this) return true;
if(o == null || !(o instanceof VarType)) return false; if(o == this) {
return true;
}
if(o == null || !(o instanceof VarType)) {
return false;
}
VarType vt = (VarType) o; VarType vt = (VarType) o;
return type == vt.type && arraydim == vt.arraydim && return type == vt.type && arraydim == vt.arraydim && InterpreterUtil.equalObjects(value, vt.value);
InterpreterUtil.equalObjects(value, vt.value);
} }
private void parseTypeString(String strtype, boolean cltype) { private void parseTypeString(String strtype, boolean cltype) {

Loading…
Cancel
Save