summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/de/fernflower/modules/decompiler/exps/FunctionExprent.java71
-rw-r--r--src/de/fernflower/struct/gen/VarType.java29
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) {