Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Incorrect order of checks for TypeBuilder GetConstructor and GetField method #53645

Merged
merged 16 commits into from
Nov 2, 2021
Merged

Fix: Incorrect order of checks for TypeBuilder GetConstructor and GetField method #53645

merged 16 commits into from
Nov 2, 2021

Conversation

BartoszKlonowski
Copy link
Contributor

@BartoszKlonowski BartoszKlonowski commented Jun 2, 2021

This pull request fixes #45988

It changes the order of checks for GetConstructor and GetField method according to the workflow of GetMethod.

Full explanation can be found in the linked issue.


Because of reordered checks of those method, unit tests had to be adjusted.
For both GetField and GetConstructor they now check whether for not generic type the element will be created without throwing.

@janvorli
Copy link
Member

janvorli commented Jun 8, 2021

cc: @eerhardt

GetConstructor and GetField had the same incorrect checks order
comparing to GetMethod as in the CoreCLR.
To keep the consistent solution, Mono has also been adjusted.
@eerhardt
Copy link
Member

@BartoszKlonowski - looks like it is still failing on mono.

@BartoszKlonowski
Copy link
Contributor Author

@eerhardt Unfortunately, I've tried to understand the order of checks for Mono - GetMethod seems to be a lot different than GetField and GetConstructor.
Can you guide me a bit through it? Otherwise I will need more time to analyse that.

@eerhardt
Copy link
Member

eerhardt commented Jul 6, 2021

@lambdageek - any thoughts on the mono checks here? Can you help @BartoszKlonowski out?

@lambdageek
Copy link
Member

@BartoszKlonowski I think you need something like this change
https://github.com/dotnet/runtime/pull/53645/files#diff-1767a4830dd55e36974e0b34848e8f736f0f5e852866b7afc0abbe078f2d5dd1R133-R134

in Mono's GetField and GetConstructor - ie instead always throwing if the type is a generic type definition
https://github.com/dotnet/runtime/pull/53645/files#diff-621fff19cdf2db5ff0e021ff669fcd0d1bb6453d59d10b3769a2be8b624a565eR1924-R1925

you should instead check whether the generic type definition that type is instantiated from is the same as the declaring type of the FieldInfo.

@BartoszKlonowski
Copy link
Contributor Author

@lambdageek Thank you! Can you verify if I understood your advice correctly?


if (type == null)
throw new ArgumentException("Type is not generic", nameof(type));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs the same code that GetMethod has:

            if (type is TypeBuilder && type.ContainsGenericParameters)
                type = type.MakeGenericType(type.GetGenericArguments());

(and same for GetField)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried, but it won't build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you also need

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern",
            Justification = "Type.MakeGenericType is used to create a typical instantiation")]


return res;
}

private static bool IsValidGetMethodType(Type type)
Copy link
Member

@eerhardt eerhardt Jul 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this method back where it was originally declared? That will make reviewing the change much easier. Also when people look at source history, will be able to see what change was made here easily. #Closed

@terrajobst terrajobst added the community-contribution Indicates that the PR has been added by a community member label Jul 19, 2021
@jeffhandley
Copy link
Member

@eerhardt Since you're the most active reviewer on this, I assigned this PR to you for follow-up/decision before the RC1 snap.

@eerhardt
Copy link
Member

@BartoszKlonowski - I left 2 pieces of feedback above. Let me know if you will address these, or if you want me to resolve them. That way we can move this PR forward.

@eerhardt
Copy link
Member

Looks like the tests are still failing:

  Starting:    System.Reflection.Emit.Tests (parallel test collections = on, max threads = 4)
    System.Reflection.Emit.Tests.TypeBuilderGetConstructor.GetConstructor_DeclaringTypeOfConstructorNotGenericTypeDefinitionOfType_ThrowsArgumentException [FAIL]
      Assert.Equal() Failure
                ↓ (pos 0)
      Expected: type
      Actual:   constructor
                ↑ (pos 0)
      Stack Trace:
        /_/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs(123,0): at System.AssertExtensions.Throws[T](String expectedParamName, Func`1 testCode)

@eerhardt
Copy link
Member

Tests are still failing:

System.Reflection.Emit.Tests.TypeBuilderGetConstructor.GetConstructor_TypeNotGeneric_ThrowsArgumentException [FAIL]
      Assert.Equal() Failure
                ? (pos 0)
      Expected: constructor
      Actual:   type
                ? (pos 0)
      Stack Trace:
        /_/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs(123,0): at System.AssertExtensions.Throws[T](String expectedParamName, Func`1 testCode)
        /_/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetConstructor.cs(77,0): at 

Are you able to run them locally? That would give you a faster turn around to get the CI green.

@BartoszKlonowski
Copy link
Contributor Author

@eerhardt I'm afraid I won't be able to finish this, sorry. I really appreciate your help and support, but analysing this and fixing the issue with tests would require much more time than I currently have...

@steveharter
Copy link
Member

@eerhardt if you want to take over this PR, please do so ASAP otherwise I recommend closing. Thanks

@eerhardt
Copy link
Member

eerhardt commented Sep 7, 2021

I'll get to this PR once I am finished with my 6.0 deliverables.

Ensure checks are consistent across GetConstructor, GetField, and GetMethod for both coreclr and mono.
Copy link
Contributor

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@eerhardt eerhardt merged commit f981785 into dotnet:main Nov 2, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Reflection community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TypeBuilder::GetConstructor and GetField type checks are in the wrong order
9 participants