Permit comparing non-empty interfaces with empty interfaces.
From-SVN: r170385
This commit is contained in:
parent
872cbb32e0
commit
7b67393dff
4 changed files with 84 additions and 14 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
32
libgo/runtime/go-interface-eface-compare.c
Normal file
32
libgo/runtime/go-interface-eface-compare.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue