]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Use G_TYPE_CHECK_INSTANCE_CAST for comparisons with interfaces
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 22 Jul 2019 10:49:53 +0000 (12:49 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Tue, 6 Aug 2019 12:00:12 +0000 (14:00 +0200)
Avoids "comparison of distinct pointer types lacks a cast" warning for
such cases.

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/objects/instance-comparison.vala [new file with mode: 0644]

index ca9a56c74b2af85e8eb14ee23636dff0ee13996d..282c49378eb8d03a0cd9adc1e1eeaf570f0b28d7 100644 (file)
@@ -2767,19 +2767,18 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        }
 
        void make_comparable_cexpression (ref DataType left_type, ref CCodeExpression cleft, ref DataType right_type, ref CCodeExpression cright) {
-               var left_type_as_struct = left_type.data_type as Struct;
-               var right_type_as_struct = right_type.data_type as Struct;
-
-               if (left_type.data_type is Class && !((Class) left_type.data_type).is_compact &&
-                   right_type.data_type is Class && !((Class) right_type.data_type).is_compact) {
-                       var left_cl = (Class) left_type.data_type;
-                       var right_cl = (Class) right_type.data_type;
-
-                       if (left_cl != right_cl) {
-                               if (left_cl.is_subtype_of (right_cl)) {
-                                       cleft = generate_instance_cast (cleft, right_cl);
-                               } else if (right_cl.is_subtype_of (left_cl)) {
-                                       cright = generate_instance_cast (cright, left_cl);
+               unowned Struct? left_type_as_struct = left_type.data_type as Struct;
+               unowned Struct? right_type_as_struct = right_type.data_type as Struct;
+               unowned ObjectTypeSymbol? left_type_as_object_type = left_type.data_type as ObjectTypeSymbol;
+               unowned ObjectTypeSymbol? right_type_as_object_type = right_type.data_type as ObjectTypeSymbol;
+
+               if (left_type_as_object_type != null && (!(left_type_as_object_type is Class) || !((Class) left_type_as_object_type).is_compact)
+                   && right_type_as_object_type != null && (!(right_type_as_object_type is Class) || !((Class) right_type_as_object_type).is_compact)) {
+                       if (left_type_as_object_type != right_type_as_object_type) {
+                               if (left_type_as_object_type.is_subtype_of (right_type_as_object_type)) {
+                                       cleft = generate_instance_cast (cleft, right_type_as_object_type);
+                               } else if (right_type_as_object_type.is_subtype_of (left_type_as_object_type)) {
+                                       cright = generate_instance_cast (cright, left_type_as_object_type);
                                }
                        }
                } else if (left_type_as_struct != null && right_type_as_struct != null) {
index 5acdd5f53abcc7593ef9660221846c4c695114cb..e9dbbef096f729aa1165d07719386a5578f39c05 100644 (file)
@@ -234,6 +234,7 @@ TESTS = \
        objects/initially-unowned.vala \
        objects/fields.vala \
        objects/gsource.vala \
+       objects/instance-comparison.vala \
        objects/interfaces.vala \
        objects/methods.vala \
        objects/paramspec.vala \
diff --git a/tests/objects/instance-comparison.vala b/tests/objects/instance-comparison.vala
new file mode 100644 (file)
index 0000000..51f02c0
--- /dev/null
@@ -0,0 +1,54 @@
+interface IFoo : Object {
+}
+
+class Bar : Object, IFoo {
+}
+
+class Manam : Bar {
+}
+
+interface IFaz : Object, IFoo {
+}
+
+class Baz : Object, IFoo, IFaz {
+}
+
+void main () {
+       {
+               Bar bar = new Bar ();
+               IFoo foo = bar;
+
+               if (foo != bar) {
+                       assert_not_reached ();
+               } else if (foo == bar) {
+                       // Well done
+               } else {
+                       assert_not_reached ();
+               }
+       }
+       {
+               IFaz faz = new Baz ();
+               IFoo foo = faz;
+
+               if (faz != foo) {
+                       assert_not_reached ();
+               } else if (foo == faz) {
+                       // Well done
+               } else {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Manam manam = new Manam ();
+               Bar bar = manam;
+
+               if (manam != bar) {
+                       assert_not_reached ();
+               } else if (manam == bar) {
+                       // Well done
+               } else {
+                       assert_not_reached ();
+               }
+       }
+}
+