From 320f9c2ae29427537e83dcb63e4028febb7f9511 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Tue, 16 Oct 2007 16:00:47 +0000 Subject: [PATCH] 2007-10-16 Mark Probst * metadata.c: Implemented correct comparing of generic classes. An inflated generic class can be equal to a non-inflated one if it is inflated with generic type variables as type arguments. Fixes bug #333798. 2007-10-16 Mark Probst * bug-333798.2.cs: added * Makefile.am: added bug-333798.2.cs svn path=/trunk/mono/; revision=87598 --- mono/metadata/ChangeLog | 7 +++++++ mono/metadata/metadata.c | 41 ++++++++++++++++++++++++++++---------- mono/tests/ChangeLog | 6 ++++++ mono/tests/Makefile.am | 3 ++- mono/tests/bug-333798.2.cs | 11 ++++++++++ 5 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 mono/tests/bug-333798.2.cs diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index bbbba172eb8..f82092e54e7 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,10 @@ +2007-10-16 Mark Probst + + * metadata.c: Implemented correct comparing of generic classes. + An inflated generic class can be equal to a non-inflated one if it + is inflated with generic type variables as type arguments. Fixes + bug #333798. + 2007-10-15 Dick Porter * monitor.c (mono_monitor_try_enter_internal): Set thread state to diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index 6f26c5f9784..d42bcdc82c0 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -1408,21 +1408,28 @@ mono_generic_inst_hash (gconstpointer data) } static gboolean -mono_generic_inst_equal (gconstpointer ka, gconstpointer kb) +mono_generic_inst_equal_full (const MonoGenericInst *a, const MonoGenericInst *b, gboolean signature_only) { - const MonoGenericInst *a = (const MonoGenericInst *) ka; - const MonoGenericInst *b = (const MonoGenericInst *) kb; int i; if (a->is_open != b->is_open || a->type_argc != b->type_argc) return FALSE; for (i = 0; i < a->type_argc; ++i) { - if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], FALSE)) + if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], signature_only)) return FALSE; } return TRUE; } +static gboolean +mono_generic_inst_equal (gconstpointer ka, gconstpointer kb) +{ + const MonoGenericInst *a = (const MonoGenericInst *) ka; + const MonoGenericInst *b = (const MonoGenericInst *) kb; + + return mono_generic_inst_equal_full (a, b, FALSE); +} + static guint mono_generic_class_hash (gconstpointer data) { @@ -3756,21 +3763,31 @@ mono_metadata_generic_class_is_valuetype (MonoGenericClass *gclass) static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2, gboolean signature_only) { - int i; MonoGenericInst *i1 = g1->context.class_inst; MonoGenericInst *i2 = g2->context.class_inst; - if (i1->type_argc != i2->type_argc || g1->is_dynamic != g2->is_dynamic) + if (g1->is_dynamic != g2->is_dynamic) return FALSE; if (!mono_metadata_class_equal (g1->container_class, g2->container_class, signature_only)) return FALSE; - for (i = 0; i < i1->type_argc; ++i) { - if (!do_mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i], signature_only)) - return FALSE; - } + if (!mono_generic_inst_equal_full (i1, i2, signature_only)) + return FALSE; return g1->is_tb_open == g2->is_tb_open; } +static gboolean +_mono_metadata_generic_class_container_equal (const MonoGenericClass *g1, MonoClass *c2, gboolean signature_only) +{ + MonoGenericInst *i1 = g1->context.class_inst; + MonoGenericInst *i2 = c2->generic_container->context.class_inst; + + if (!mono_metadata_class_equal (g1->container_class, c2, signature_only)) + return FALSE; + if (!mono_generic_inst_equal_full (i1, i2, signature_only)) + return FALSE; + return !g1->is_tb_open; +} + guint mono_metadata_generic_context_hash (const MonoGenericContext *context) { @@ -3843,6 +3860,10 @@ mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only return TRUE; if (c1->generic_class && c2->generic_class) return _mono_metadata_generic_class_equal (c1->generic_class, c2->generic_class, signature_only); + if (c1->generic_class && c2->generic_container) + return _mono_metadata_generic_class_container_equal (c1->generic_class, c2, signature_only); + if (c1->generic_container && c2->generic_class) + return _mono_metadata_generic_class_container_equal (c2->generic_class, c1, signature_only); if ((c1->byval_arg.type == MONO_TYPE_VAR) && (c2->byval_arg.type == MONO_TYPE_VAR)) return mono_metadata_generic_param_equal ( c1->byval_arg.data.generic_param, c2->byval_arg.data.generic_param, signature_only); diff --git a/mono/tests/ChangeLog b/mono/tests/ChangeLog index ad01bcac9d3..0edd2ee48db 100644 --- a/mono/tests/ChangeLog +++ b/mono/tests/ChangeLog @@ -1,3 +1,9 @@ +2007-10-16 Mark Probst + + * bug-333798.2.cs: added + + * Makefile.am: added bug-333798.2.cs + 2007-10-05 Rodrigo Kumpera * generic_type_definition_encoding.2.cs: added, this tests diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index 1ee72d9ad5e..78e4640fdca 100644 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -303,7 +303,8 @@ TEST_CS2_SRC = \ anonarray.2.cs \ ienumerator-interfaces.2.cs \ generic_type_definition_encoding.2.cs \ - generic_type_definition.2.cs + generic_type_definition.2.cs \ + bug-333798.2.cs TEST_IL2_SRC = find-method.2.il \ bug-79215.2.il \ diff --git a/mono/tests/bug-333798.2.cs b/mono/tests/bug-333798.2.cs new file mode 100644 index 00000000000..7c5b4456525 --- /dev/null +++ b/mono/tests/bug-333798.2.cs @@ -0,0 +1,11 @@ +public class Gen { + public static Gen[] newSelfArr () { + return null; + } +} + +public class main { + public static void Main () { + Gen.newSelfArr (); + } +} -- 2.25.1