Skip to content

Validate invalid base type declarations in ILVerify#129118

Open
pkuyo wants to merge 13 commits into
dotnet:mainfrom
pkuyo:fix-ilverify-119536
Open

Validate invalid base type declarations in ILVerify#129118
pkuyo wants to merge 13 commits into
dotnet:mainfrom
pkuyo:fix-ilverify-119536

Conversation

@pkuyo

@pkuyo pkuyo commented Jun 8, 2026

Copy link
Copy Markdown

Fixes #119536

This adds ILVerify validation for invalid class base type declarations.

The original issue reports a case where ILAsm accepts a type declared with
extends object, but the resulting type cannot be loaded by the runtime.
ILVerify previously accepted that assembly without reporting an error.

This change reports InvalidBaseType for invalid base type declarations rather
than special-casing only the exact extends object spelling.

Tests added in BaseTypeTests.il:

  • ObjectTypeSpecBase_InvalidType_InvalidBaseType

    • Covers the original repro: a class declared with extends object.
    • Expected result: InvalidBaseType.
  • NilBaseInterface_ValidType_Valid

    • Ensures interfaces with no class base continue to verify successfully.
  • GenericClassTypeSpecBase_ValidType_Valid

    • Ensures valid generic class TypeSpec bases are still accepted.
  • ValueTypeBase_InvalidType_InvalidBaseType

    • Ensures a non-generic value type cannot be used as a class base.
  • GenericValueTypeSpecBase_InvalidType_InvalidBaseType

    • Ensures a generic value type instantiation cannot be used as a class base.

@github-actions github-actions Bot added the area-Tools-ILVerification Issues related to ilverify tool and IL verification in general label Jun 8, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jun 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/jit-contrib
See info in area-owners.md if you want to be subscribed.

@pkuyo

pkuyo commented Jun 8, 2026

Copy link
Copy Markdown
Author

@dotnet-policy-service agree

Comment thread src/coreclr/tools/ILVerification/TypeVerifier.cs Outdated
Comment thread src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs Outdated
Comment thread src/coreclr/tools/ILVerification/TypeVerifier.cs Outdated
@pkuyo

pkuyo commented Jun 17, 2026

Copy link
Copy Markdown
Author

Hi @jkotas, just checking in on this PR. I’ve addressed the feedback and made the requested updates. Please let me know if there’s anything else I should adjust. Thanks!

Comment thread src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs Outdated
Comment thread src/coreclr/tools/ILVerification.Tests/ILTests/CastingTests.il Outdated
Comment thread src/coreclr/tools/ILVerification/TypeVerifier.cs Outdated
Comment thread src/coreclr/tools/ILVerification/TypeVerifier.cs Outdated
@pkuyo

pkuyo commented Jun 30, 2026

Copy link
Copy Markdown
Author

Thanks for the review. I updated the PR to address the latest feedback, The TypeSpec validation now follows the ECMA-335 augment behavior.

Please let me know if there is anything else I should adjust.

@MichalStrehovsky

MichalStrehovsky commented Jul 1, 2026

Copy link
Copy Markdown
Member

(Edited to fix issue number)

I wonder if we should approach this from an angle that also allows to address #4945

  • Add ParseTypeSpec to EcmaSignatureParser.
  • Do the validation in EcmaSignatureParser (this allows us getting rid of the ILVERIFICATION ifdef, because this could be a ReportInvalidTypeSpec partial method on EcmaSignatureParser: this matches more closely how invalid things are reported (e.g. in ILImporter.cs).

@jkotas

jkotas commented Jul 1, 2026

Copy link
Copy Markdown
Member
  • Add ParseTypeSpec to EcmaSignatureParser.
  • Do the validation in EcmaSignatureParser (this allows us getting rid of the ILVERIFICATION ifdef, because this could be a ReportInvalidTypeSpec partial method on EcmaSignatureParser: this matches more closely how invalid things are reported (e.g. in ILImporter.cs).

Yes, I think it would look better. @pkuyo Could you please implement it?

}
else
{
if (baseType.Kind == HandleKind.TypeSpecification &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should not be needed. It is covered by the resolvedBaseType.IsValueType || resolvedBaseType.IsInterface || !resolvedBaseType.IsDefType check below.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks. I simplified this to a smaller TypeSpec-specific check.

The resolvedBaseType.IsValueType || resolvedBaseType.IsInterface || !resolvedBaseType.IsDefType check alone does not catch the #119536 case, because a TypeSpec that resolves to System.Object passes those resolved-type checks. The extra TypeSpec check is only for that context-specific extends validation.

@jkotas jkotas Jul 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok, I see.

It does not feel right to have a different "spec" for typespecs depending on the context. Maybe we should be more restrictive in the default type spec parser like you had it originally and update the augments doc to match.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@MichalStrehovsky Do you have opinion about this? Should we stick with the stricter definition of typespec to avoid bifurcating typespec spec?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Stricter sounds good to me. If we find out there are mainstream compilers breaking it, we could relax I guess. (MSVC doesn't count, it never even pretended to target ECMA-335.)

Comment thread src/coreclr/tools/ILVerification/TypeVerifier.cs Outdated
@pkuyo

pkuyo commented Jul 1, 2026

Copy link
Copy Markdown
Author
  • Add ParseTypeSpec to EcmaSignatureParser.
  • Do the validation in EcmaSignatureParser (this allows us getting rid of the ILVERIFICATION ifdef, because this could be a ReportInvalidTypeSpec partial method on EcmaSignatureParser: this matches more closely how invalid things are reported (e.g. in ILImporter.cs).

Yes, I think it would look better. @pkuyo Could you please implement it?

Sure, thanks. I’ll implement it this way and update the PR.

@pkuyo

pkuyo commented Jul 1, 2026

Copy link
Copy Markdown
Author

(Edited to fix issue number)

I wonder if we should approach this from an angle that also allows to address #4945

  • Add ParseTypeSpec to EcmaSignatureParser.
  • Do the validation in EcmaSignatureParser (this allows us getting rid of the ILVERIFICATION ifdef, because this could be a ReportInvalidTypeSpec partial method on EcmaSignatureParser: this matches more closely how invalid things are reported (e.g. in ILImporter.cs).

Thanks, I reworked this to use the EcmaSignatureParser approach.

The TypeSpec validation is now done through ParseTypeSpec / ReportInvalidTypeSpec, and I addedCoverage-relatedto #4945.

For CMOD_OPT/CMOD_REQ, I kept the check simple for now: it reports a TypeSpec reference while parsing another TypeSpec, but does not try to distinguish whether it actually forms a cycle. Full cycle detection would need extra tracking for the active TypeSpec resolution stack, since the current TypeSpec is not in the cache yet.

I wasn't sure that extra state was necessary for this PR, so I wanted to check before adding it.

@MichalStrehovsky

Copy link
Copy Markdown
Member

For CMOD_OPT/CMOD_REQ, I kept the check simple for now: it reports a TypeSpec reference while parsing another TypeSpec, but does not try to distinguish whether it actually forms a cycle. Full cycle detection would need extra tracking for the active TypeSpec resolution stack, since the current TypeSpec is not in the cache yet.

We shouldn't allow TypeSpec as a modifier. It only causes problems. If the augment says we allow it, we should update the augment. We can capture the reason so that somebody doesn't try to relax it without thinking about the consequences (@jkotas do you agree?). I think this recently came up in #123819 and we decided not to handle TypeSpec either, but GitHub makes it really hard to find the relevant comment.

@jkotas

jkotas commented Jul 1, 2026

Copy link
Copy Markdown
Member

We can capture the reason so that somebody doesn't try to relax it without thinking about the consequences (@jkotas do you agree?)

Yes

Comment thread src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs Outdated
Comment thread src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs Outdated
Comment thread src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs Outdated
Comment thread src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs Outdated
table, TypeRef table, or TypeSpec table. However, these tokens are encoded and compressed –
see §II.23.2.8 for details. Furthermore, if a row in the TypeSpec table is indicated,
it must not create cycle.
table or TypeRef table. However, these tokens are encoded and compressed –

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not proposing any actual change anymore. Both original and proposed replacements are identical. If we want to propose any change here, it should be to add a sentence that explains why typespecs are not allowed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated. I added a sentence explaining that TypeSpec tokens are not valid in this position because allowing them could form recursive TypeSpec encodings.

Comment thread docs/design/specs/Ecma-335-Augments.md Outdated
then there should be a clarification that cycles are nonetheless not
permitted, and ideally readers would detect such cycles and handle the
error with a suitable message rather than a stack overflow.
Allowing TypeSpec custom modifier types also creates a path for

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Allowing TypeSpec custom modifier types also creates a path for
Allowing TypeSpec custom modifier types creates a path for

Comment thread docs/design/specs/Ecma-335-Augments.md Outdated
Comment on lines +156 to +157
recursive TypeSpec encodings, which has caused problems in runtimes
and tools. Such metadata should be rejected rather than cycle-detected.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
recursive TypeSpec encodings, which has caused problems in runtimes
and tools. Such metadata should be rejected rather than cycle-detected.
recursive TypeSpec encodings that are complicated to detect. Such metadata should be rejected rather than cycle-detected.

Related issues:

* https://github.com/dotnet/roslyn/issues/7971
* https://github.com/dotnet/runtime/issues/4945

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
* https://github.com/dotnet/runtime/issues/4945
* https://github.com/dotnet/runtime/pull/123819#discussion_r2810397721

by a TypeRef or TypeDef metadata token. TypeSpec tokens in this
position should be treated as invalid metadata.

Allowing TypeSpec custom modifier types creates a path for

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Could you please reformat this to have similar text width, and add new line before "Related issues"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sure, I’ve updated it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Tools-ILVerification Issues related to ilverify tool and IL verification in general 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.

ilverify fails to warn about invalid class declaration

3 participants