- else if value2.mtype.ctype != "val*" then
- self.add("{res} = 0; /* incompatible types {value1.mtype} vs. {value2.mtype}*/")
- else if value1.mtype.is_tagged then
- self.add("{res} = ({value2} != NULL) && ({self.autobox(value2, value1.mtype)} == {value1});")
+ return res
+ end
+
+ # Complex case: value2 has a different representation
+ # Thus, it should be checked if `value2` is type-compatible with `value1`
+ # This compatibility is done statically if possible and dynamically else
+
+ # Conjunction (ands) of dynamic tests according to the static knowledge
+ var tests = new Array[String]
+
+ var t2 = value2.mcasttype
+ if t2 isa MNullableType then
+ # The destination type cannot be null
+ tests.add("({value2} != NULL)")
+ t2 = t2.mtype
+ else if t2 isa MNullType then
+ # `value2` is known to be null, thus incompatible with a primitive
+ self.add("{res} = 0; /* incompatible types {t1} vs. {t2}*/")
+ return res
+ end
+
+ if t2 == t1 then
+ # Same type but different representation.
+ else if t2.is_c_primitive then
+ # Type of `value2` is a different primitive type, thus incompatible
+ self.add("{res} = 0; /* incompatible types {t1} vs. {t2}*/")
+ return res
+ else if t1.is_tagged then
+ # To be equal, `value2` should also be correctly tagged
+ tests.add("({extract_tag(value2)} == {t1.tag_value})")