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

CodeGen: fix generated DeepCopy method to call RecordObject earlier #2135

Merged

Conversation

ReubenBond
Copy link
Member

Currently generated DeepCopy method incorrectly calls RecordObject after copying fields instead of before. This results in circular references involving being incorrectly serialized, resulting in a loss of referential equality.

The fix is to simply emit the call to RecordObject before the field-copying calls.

This was not failing in our test suite (Serialize_CircularReference) because the assembly holding the recursively defined type has the [SkipCodeGeneration] attribute, so a serializer was not being generated and so the fallback serializer was being used.

@@ -60,7 +62,7 @@ public override bool Equals(object x, object y)

public override int GetHashCode(object obj)
{
return obj == null ? 0 : obj.GetHashCode();
return obj == null ? 0 : RuntimeHelpers.GetHashCode(obj);
Copy link
Member Author

Choose a reason for hiding this comment

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

Not strictly required for this change, but a potential bug. Just as we use object.ReferenceEquals above this, we should call RuntimeHelpers.GetHashCode rather than obj.GetHashCode so that we are not dependent on user-defined implementations of GetHashCode. It's not likely to cause an issue, but it's possible.

@ReubenBond ReubenBond force-pushed the fix-codegen-deepcopy-recordobject branch from 92628e6 to 0271081 Compare September 10, 2016 08:12
@@ -21,6 +21,8 @@

namespace UnitTests.Serialization
{
using TestGrainInterfaces;

/// <summary>
Copy link
Member Author

Choose a reason for hiding this comment

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

Instead of redefining CircularTest1, we use the implementation in TestGrainInterfaces because that implementation has a generated serializer whereas this assembly does not, due to [assembly: SkipCodeGeneration] attribute.

@sergeybykov sergeybykov merged commit 8a8af6a into dotnet:master Sep 12, 2016
@ReubenBond ReubenBond deleted the fix-codegen-deepcopy-recordobject branch September 22, 2016 06:29
@github-actions github-actions bot locked and limited conversation to collaborators Dec 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants