From: ian Date: Tue, 22 Feb 2011 02:52:55 +0000 (+0000) Subject: Permit comparing non-empty interfaces with empty interfaces. X-Git-Tag: upstream/4.9.2~22640 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=739bad04e9c0d30d9342cef8dc2341089db028d8;p=platform%2Fupstream%2Flinaro-gcc.git Permit comparing non-empty interfaces with empty interfaces. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170385 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 3d687a6..8b064e6 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6270,9 +6270,9 @@ Expression::comparison_tree(Translate_context* context, Operator op, else if (left_type->interface_type() != NULL && right_type->interface_type() != NULL) { - if (left_type->interface_type()->is_empty()) + if (left_type->interface_type()->is_empty() + && right_type->interface_type()->is_empty()) { - gcc_assert(right_type->interface_type()->is_empty()); static tree empty_interface_compare_decl; left_tree = Gogo::call_builtin(&empty_interface_compare_decl, location, @@ -6288,9 +6288,9 @@ Expression::comparison_tree(Translate_context* context, Operator op, // This can panic if the type is uncomparable. TREE_NOTHROW(empty_interface_compare_decl) = 0; } - else + else if (!left_type->interface_type()->is_empty() + && !right_type->interface_type()->is_empty()) { - gcc_assert(!right_type->interface_type()->is_empty()); static tree interface_compare_decl; left_tree = Gogo::call_builtin(&interface_compare_decl, location, @@ -6306,6 +6306,32 @@ Expression::comparison_tree(Translate_context* context, Operator op, // This can panic if the type is uncomparable. TREE_NOTHROW(interface_compare_decl) = 0; } + else + { + if (left_type->interface_type()->is_empty()) + { + gcc_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ); + std::swap(left_type, right_type); + std::swap(left_tree, right_tree); + } + gcc_assert(!left_type->interface_type()->is_empty()); + gcc_assert(right_type->interface_type()->is_empty()); + static tree interface_empty_compare_decl; + left_tree = Gogo::call_builtin(&interface_empty_compare_decl, + location, + "__go_interface_empty_compare", + 2, + integer_type_node, + TREE_TYPE(left_tree), + left_tree, + TREE_TYPE(right_tree), + right_tree); + if (left_tree == error_mark_node) + return error_mark_node; + // This can panic if the type is uncomparable. + TREE_NOTHROW(interface_empty_compare_decl) = 0; + } + right_tree = build_int_cst_type(integer_type_node, 0); } diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 9274b36..814d7ed 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -352,6 +352,7 @@ runtime_files = \ runtime/go-int-array-to-string.c \ runtime/go-int-to-string.c \ runtime/go-interface-compare.c \ + runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c \ runtime/go-lock-os-thread.c \ runtime/go-map-delete.c \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index e4ec149..11352cf 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -179,6 +179,7 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \ runtime/go-getgoroot.c runtime/go-go.c runtime/go-gomaxprocs.c \ runtime/go-int-array-to-string.c runtime/go-int-to-string.c \ runtime/go-interface-compare.c \ + runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c runtime/go-lock-os-thread.c \ runtime/go-map-delete.c runtime/go-map-index.c \ runtime/go-map-len.c runtime/go-map-range.c \ @@ -222,16 +223,17 @@ am__objects_3 = go-append.lo go-assert.lo go-assert-interface.lo \ go-defer.lo go-deferred-recover.lo go-eface-compare.lo \ go-eface-val-compare.lo go-getgoroot.lo go-go.lo \ go-gomaxprocs.lo go-int-array-to-string.lo go-int-to-string.lo \ - go-interface-compare.lo go-interface-val-compare.lo \ - go-lock-os-thread.lo go-map-delete.lo go-map-index.lo \ - go-map-len.lo go-map-range.lo go-nanotime.lo go-new-channel.lo \ - go-new-map.lo go-new.lo go-note.lo go-panic.lo \ - go-panic-defer.lo go-print.lo go-rec-big.lo go-rec-nb-big.lo \ - go-rec-nb-small.lo go-rec-small.lo go-recover.lo go-reflect.lo \ - go-reflect-call.lo go-reflect-chan.lo go-reflect-map.lo \ - go-rune.lo go-runtime-error.lo go-sched.lo go-select.lo \ - go-semacquire.lo go-send-big.lo go-send-nb-big.lo \ - go-send-nb-small.lo go-send-small.lo go-signal.lo go-strcmp.lo \ + go-interface-compare.lo go-interface-eface-compare.lo \ + go-interface-val-compare.lo go-lock-os-thread.lo \ + go-map-delete.lo go-map-index.lo go-map-len.lo go-map-range.lo \ + go-nanotime.lo go-new-channel.lo go-new-map.lo go-new.lo \ + go-note.lo go-panic.lo go-panic-defer.lo go-print.lo \ + go-rec-big.lo go-rec-nb-big.lo go-rec-nb-small.lo \ + go-rec-small.lo go-recover.lo go-reflect.lo go-reflect-call.lo \ + go-reflect-chan.lo go-reflect-map.lo go-rune.lo \ + go-runtime-error.lo go-sched.lo go-select.lo go-semacquire.lo \ + go-send-big.lo go-send-nb-big.lo go-send-nb-small.lo \ + go-send-small.lo go-signal.lo go-strcmp.lo \ go-string-to-byte-array.lo go-string-to-int-array.lo \ go-strplus.lo go-strslice.lo go-trampoline.lo go-type-eface.lo \ go-type-error.lo go-type-identity.lo go-type-interface.lo \ @@ -764,6 +766,7 @@ runtime_files = \ runtime/go-int-array-to-string.c \ runtime/go-int-to-string.c \ runtime/go-interface-compare.c \ + runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c \ runtime/go-lock-os-thread.c \ runtime/go-map-delete.c \ @@ -2067,6 +2070,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-int-array-to-string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-int-to-string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-compare.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-eface-compare.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-val-compare.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-lock-os-thread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-main.Po@am__quote@ @@ -2358,6 +2362,13 @@ go-interface-compare.lo: runtime/go-interface-compare.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-interface-compare.lo `test -f 'runtime/go-interface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-compare.c +go-interface-eface-compare.lo: runtime/go-interface-eface-compare.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-interface-eface-compare.lo -MD -MP -MF $(DEPDIR)/go-interface-eface-compare.Tpo -c -o go-interface-eface-compare.lo `test -f 'runtime/go-interface-eface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-eface-compare.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-interface-eface-compare.Tpo $(DEPDIR)/go-interface-eface-compare.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-interface-eface-compare.c' object='go-interface-eface-compare.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-interface-eface-compare.lo `test -f 'runtime/go-interface-eface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-eface-compare.c + go-interface-val-compare.lo: runtime/go-interface-val-compare.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-interface-val-compare.lo -MD -MP -MF $(DEPDIR)/go-interface-val-compare.Tpo -c -o go-interface-val-compare.lo `test -f 'runtime/go-interface-val-compare.c' || echo '$(srcdir)/'`runtime/go-interface-val-compare.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-interface-val-compare.Tpo $(DEPDIR)/go-interface-val-compare.Plo diff --git a/libgo/runtime/go-interface-eface-compare.c b/libgo/runtime/go-interface-eface-compare.c new file mode 100644 index 0000000..9de8424 --- /dev/null +++ b/libgo/runtime/go-interface-eface-compare.c @@ -0,0 +1,32 @@ +/* go-interface-eface-compare.c -- compare non-empty and empty interface. + + Copyright 2011 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. */ + +#include "interface.h" + +/* Compare a non-empty interface value with an empty interface value. + Return 0 for equal, not zero for not equal (return value is like + strcmp). */ + +int +__go_interface_empty_compare (struct __go_interface left, + struct __go_empty_interface right) +{ + const struct __go_type_descriptor *left_descriptor; + + if (left.__methods == NULL && right.__type_descriptor == NULL) + return 0; + if (left.__methods == NULL || right.__type_descriptor == NULL) + return 1; + left_descriptor = left.__methods[0]; + if (!__go_type_descriptors_equal (left_descriptor, right.__type_descriptor)) + return 1; + if (__go_is_pointer_type (left_descriptor)) + return left.__object == right.__object ? 0 : 1; + if (!left_descriptor->__equalfn (left.__object, right.__object, + left_descriptor->__size)) + return 1; + return 0; +}