From de249340fc5a0446701dcf8a117aa69ad6dd3f71 Mon Sep 17 00:00:00 2001 From: Stiver Date: Wed, 13 Aug 2014 22:03:09 +0200 Subject: [PATCH] Fixed 'IDEA-128594: Variable type incorrectly set to boolean' --- .../decompiler/exps/FunctionExprent.java | 71 ++++++++++--------- src/de/fernflower/struct/gen/VarType.java | 29 ++++++-- 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/src/de/fernflower/modules/decompiler/exps/FunctionExprent.java b/src/de/fernflower/modules/decompiler/exps/FunctionExprent.java index 2610b33..2f75b71 100644 --- a/src/de/fernflower/modules/decompiler/exps/FunctionExprent.java +++ b/src/de/fernflower/modules/decompiler/exps/FunctionExprent.java @@ -368,43 +368,48 @@ public class FunctionExprent extends Exprent { break; case FUNCTION_AND: case FUNCTION_OR: - case FUNCTION_XOR: - if(type1.type == CodeConstants.TYPE_BOOLEAN && - ((type1.convinfo & VarType.FALSEBOOLEAN) != 0 || type2.type != CodeConstants.TYPE_BOOLEAN)) { - result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); - } - if(type2.type == CodeConstants.TYPE_BOOLEAN && - ((type2.convinfo & VarType.FALSEBOOLEAN) != 0 || type1.type != CodeConstants.TYPE_BOOLEAN)) { - result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR); + case FUNCTION_XOR: + { + 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); + } + + if(type2.type == CodeConstants.TYPE_BOOLEAN) { + result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR); + } + } } break; case FUNCTION_EQ: case FUNCTION_NE: - - if(type1.type == CodeConstants.TYPE_BOOLEAN) { - - if(type2.isStrictSuperset(type1)) { - result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); - } else { - if(param1.type == Exprent.EXPRENT_CONST && !((ConstExprent)param1).hasBooleanValue()) { - if(param2.type != Exprent.EXPRENT_CONST || !((ConstExprent)param2).hasBooleanValue()) { // variable or not boolean constant - result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); - } - } - } - } - - if(type2.type == CodeConstants.TYPE_BOOLEAN) { - - if(type1.isStrictSuperset(type2)) { - 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); - } - } - } + { + if(type1.type == CodeConstants.TYPE_BOOLEAN) { + + if(type2.isStrictSuperset(type1)) { + + result.addMinTypeExprent(param1, VarType.VARTYPE_BYTECHAR); + + } else { // both are booleans + + 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(param2, VarType.VARTYPE_BYTECHAR); + } + } + + } else if(type2.type == CodeConstants.TYPE_BOOLEAN) { + + if(type1.isStrictSuperset(type2)) { + result.addMinTypeExprent(param2, VarType.VARTYPE_BYTECHAR); + } + } } } diff --git a/src/de/fernflower/struct/gen/VarType.java b/src/de/fernflower/struct/gen/VarType.java index c01bcf1..2ddde86 100644 --- a/src/de/fernflower/struct/gen/VarType.java +++ b/src/de/fernflower/struct/gen/VarType.java @@ -114,7 +114,11 @@ public class VarType { // TODO: optimize switch v.convinfo = convinfo; return v; } - + + public boolean isFalseBoolean() { + return (convinfo & VarType.FALSEBOOLEAN) != 0; + } + public boolean isSuperset(VarType 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 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)) { return type2; } else if(type2.isSuperset(type1)) { @@ -189,6 +197,10 @@ public class VarType { // TODO: optimize switch // type1 and type2 must not be null 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)) { return type1; } else if(type2.isSuperset(type1)) { @@ -232,12 +244,17 @@ public class VarType { // TODO: optimize switch } 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; - return type == vt.type && arraydim == vt.arraydim && - InterpreterUtil.equalObjects(value, vt.value); + VarType vt = (VarType) o; + return type == vt.type && arraydim == vt.arraydim && InterpreterUtil.equalObjects(value, vt.value); } private void parseTypeString(String strtype, boolean cltype) {