diff options
author | imhameed <imhameed@microsoft.com> | 2020-08-25 20:42:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-25 20:42:44 +0300 |
commit | 1f3fbedc39713faf331b4d14df58a5b1cd71ce3c (patch) | |
tree | 61aa873da86d41295b92273f9e25b6d957f7bf59 | |
parent | 45d996b7ba059ad88d9b3f74182e3a9da16da34d (diff) |
[runtime] Catch attempts to create enum types with an underlying type that is itself an incomplete enum type. (#20282)
* Catch attempts to create enum types with an underlying type that is itself an incomplete enum type.
Previously, only non-enum types containing fields with incomplete enum
types were forbidden.
* Permit static constant fields with incomplete types if the incomplete type is the type currently being defined
Co-authored-by: Alexis Christoforides <alexis@thenull.net>
-rw-r--r-- | mcs/class/corlib/Test/System.Reflection.Emit/EnumBuilderTest.cs | 22 | ||||
-rw-r--r-- | mono/metadata/sre.c | 8 |
2 files changed, 27 insertions, 3 deletions
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/EnumBuilderTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/EnumBuilderTest.cs index 5432040c523..6a322c6c5e9 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/EnumBuilderTest.cs +++ b/mcs/class/corlib/Test/System.Reflection.Emit/EnumBuilderTest.cs @@ -317,6 +317,28 @@ namespace MonoTests.System.Reflection.Emit } [Test] + public void TestCreateInvalidEnumWithAnIncompleteUnderlyingEnumType () + { + var mb = GenerateModule (); + var incomplete = GenerateEnum (mb); + GenerateField (incomplete); + + var eb = mb.DefineEnum ( + _enumNamespace + ".IncompleteUnderlying", + TypeAttributes.Public, + incomplete); + + bool caught = false; + try { + var t = eb.CreateType (); + } catch (TypeLoadException exn) { + caught = true; + } + if (!caught) + Assert.Fail ("Expected CreateType of a broken type to throw TLE"); + } + + [Test] public void TestEnumBuilderTokenUsable () { // Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=58361 // Create an EnumBuilder and use it in an ILGenerator that consumes its token. diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index 41abcebf94f..d2ee825173f 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -3712,9 +3712,11 @@ typebuilder_setup_one_field (MonoDynamicImage *dynamic_image, MonoClass *klass, if (klass->enumtype && strcmp (field->name, "value__") == 0) // used by enum classes to store the instance value field->type->attrs |= FIELD_ATTRIBUTE_RT_SPECIAL_NAME; - if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) { - mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name); - goto leave; + if (!mono_type_get_underlying_type (field->type)) { + if (!(klass->enumtype && mono_metadata_type_equal (field->type, m_class_get_byval_arg (klass)))) { + mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name); + goto leave; + } } if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) { |