From: Rico Tzschichholz Date: Mon, 22 Jul 2019 10:49:53 +0000 (+0200) Subject: codegen: Use G_TYPE_CHECK_INSTANCE_CAST for comparisons with interfaces X-Git-Tag: 0.45.90~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5744eed9e8adcf7714bab17042188a508c510922;p=thirdparty%2Fvala.git codegen: Use G_TYPE_CHECK_INSTANCE_CAST for comparisons with interfaces Avoids "comparison of distinct pointer types lacks a cast" warning for such cases. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index bef379bf1..783aa06e8 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2808,19 +2808,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) { diff --git a/configure.ac b/configure.ac index aa8097b23..4dc975450 100644 --- a/configure.ac +++ b/configure.ac @@ -123,6 +123,7 @@ TEST_EXTRA_CFLAGS="-Werror=init-self \ -Werror=uninitialized \ -Werror=int-to-pointer-cast \ -Werror=pointer-to-int-cast \ +-Werror=compare-distinct-pointer-types \ -Wformat=2 \ -Werror=format-security \ -Werror=format-nonliteral \ diff --git a/tests/Makefile.am b/tests/Makefile.am index dfa15aa95..da383549b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -308,6 +308,7 @@ TESTS = \ objects/field-leading-digit.test \ objects/fields.vala \ objects/gsource.vala \ + objects/instance-comparison.vala \ objects/interface_only.vala \ objects/interfaces.vala \ objects/interface-generics.vala \ diff --git a/tests/objects/instance-comparison.vala b/tests/objects/instance-comparison.vala new file mode 100644 index 000000000..51f02c00c --- /dev/null +++ b/tests/objects/instance-comparison.vala @@ -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 (); + } + } +} +