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 a native integer decoding bug #43885

Merged
4 commits merged into from
May 6, 2020
Merged

Fix a native integer decoding bug #43885

4 commits merged into from
May 6, 2020

Conversation

333fred
Copy link
Member

@333fred 333fred commented May 1, 2020

We weren't consuming an index when decoding type parameters or dynamic types, meaning that we could get into a scenario where the remaining flags are applying to the wrong types. I also tightened our assertions around ignored indexes.

@cston for review.

We weren't consuming an index when decoding type parameters or dynamic types, meaning that we could get into a scenario where the remaining flags are applying to the wrong types.
@333fred 333fred requested review from cston and a team May 1, 2020 21:26
@@ -62,6 +62,7 @@ private TypeSymbol TransformType(TypeSymbol type)
return TransformPointerType((PointerTypeSymbol)type);
case TypeKind.TypeParameter:
case TypeKind.Dynamic:
IgnoreIndex();
Copy link
Member Author

Choose a reason for hiding this comment

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

This part is the bug fix.

private void IgnoreIndex()
{
var index = Increment();
Debug.Assert(!_transformFlags[index]);
Copy link
Member

@cston cston May 1, 2020

Choose a reason for hiding this comment

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

Debug.Assert(!_transformFlags[index]) [](start = 12, length = 37)

This may fail for handwritten attribute data.

Please add a test.

class C<T, U, V>
{{
public {sourceType} F;
}}
Copy link
Member

@cston cston May 1, 2020

Choose a reason for hiding this comment

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

Please consider writing out all the cases inline as separate fields in a single test, for readability and to match other tests.

}}
", options: TestOptions.ReleaseDll, parseOptions: TestOptions.RegularPreview, symbolValidator: symbolValidator);

void symbolValidator(ModuleSymbol module)
Copy link
Member

Choose a reason for hiding this comment

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

void [](start = 12, length = 4)

Consider making static or inline in CompileAndVerify to match the other tests.

@@ -125,6 +128,12 @@ private int Increment()
throw new ArgumentException();
Copy link
Member

@gafter gafter May 1, 2020

Choose a reason for hiding this comment

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

throw new ArgumentException [](start = 12, length = 27)

If we're worried about handwritten attribute data, this could crash the compiler as well. Please add a test. #Resolved

Copy link
Member Author

@333fred 333fred May 1, 2020

Choose a reason for hiding this comment

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

It can't crash the compiler, it's caught above. I already tried to crash it with this :). #Resolved

Copy link
Member

Choose a reason for hiding this comment

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

There should be existing tests for this case.


In reply to: 418757779 [](ancestors = 418757779)

gafter
gafter previously approved these changes May 1, 2020
Copy link
Member

@gafter gafter left a comment

Choose a reason for hiding this comment

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

:shipit:

@@ -71,6 +97,7 @@ private TypeSymbol TransformType(TypeSymbol type)
return TransformNamedType((NamedTypeSymbol)type);
default:
Debug.Assert(type.TypeKind == TypeKind.Error);
_decodeStatus = DecodeStatus.FailedToErrorType;
throw new ArgumentException();
Copy link
Member

Choose a reason for hiding this comment

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

Consider extracting a helper method with DecodeStatus argument.

{
NotFailed,
FailedToErrorType,
FailedToBadMetadata,
Copy link
Member

Choose a reason for hiding this comment

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

Consider renaming fields, perhaps:

enum DecodeStatus
{
    Succeeded,
    ErrorType,
    BadMetadata,
}

}

private readonly ImmutableArray<bool> _transformFlags;
private int _index;
private DecodeStatus _decodeStatus;
Copy link
Member

Choose a reason for hiding this comment

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

DecodeStatus _decodeStatus [](start = 16, length = 26)

Is this field needed?

Rather than using a field, could we just throw ArgumentException for cases that have error types (where we catch the exception locally and return the original type), and throw UnsupportMetadataTypeSymbol for case where we fail completely?

if (_transformFlags[index])
{
_decodeStatus = DecodeStatus.FailedToBadMetadata;
throw new ArgumentException();
Copy link
Member

Choose a reason for hiding this comment

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

throw new ArgumentException(); [](start = 16, length = 30)

Are we testing this case?

Copy link
Member

@cston cston 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 for fixing this.

@333fred 333fred requested a review from gafter May 2, 2020 07:36
@333fred
Copy link
Member Author

333fred commented May 2, 2020

@gafter there have been more changes since your review, probably needs another look.

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

We should either produce successfully decoded type, or ignore the malformed attribute and return original type. This is how I believe we always handle attributes like that.

@AlekseyTs AlekseyTs dismissed their stale review May 2, 2020 14:52

Obsolete

@AlekseyTs
Copy link
Contributor

AlekseyTs commented May 2, 2020

We should either produce successfully decoded type, or ignore the malformed attribute and return original type. This is how I believe we always handle attributes like that.

Actually, it looks like only nullable decoder ignores malformed attribute, which probably makes sense because annotations can cause only warnings. #Closed

@333fred
Copy link
Member Author

333fred commented May 2, 2020

Actually, it looks like only nullable decoder ignores malformed attribute, which probably makes sense because annotations can cause only warnings.

Yeah. My concern with bad nint data is that it will affect codegen.

@gafter gafter dismissed their stale review May 5, 2020 23:25

revoking review

}
catch (UnsupportedSignatureContent)
{
return new UnsupportedMetadataTypeSymbol();
}
catch (ArgumentException)
Copy link
Member

@gafter gafter May 5, 2020

Choose a reason for hiding this comment

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

ArgumentException [](start = 19, length = 17)

Using ArgumentException to manage these failure modes (line 88) seems a bit dangerous, as you can't have complete confidence that it was one thrown as part of decoding in this class. It might be better to make a custom exception (private?) for this purpose/

Copy link
Member

@gafter gafter left a comment

Choose a reason for hiding this comment

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

I suggest you stop using ArgumentException in the decoder, because when you catch it you cannot be sure it was thrown in your code on line 88. Instead perhaps use a new private exception for that purpose.

Otherwise looks good.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

Auto-approval

@ghost ghost merged commit cb1f6ee into dotnet:master May 6, 2020
@333fred 333fred deleted the nint-decode-bug branch May 6, 2020 19:48
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants