Skip to content

Using a non-null constant expression bound to a literal variable of a less-specific type generates invalid IL #18319

@IS4Code

Description

@IS4Code

It is possible to define literal values that are the result of upcasting a literal to a less specific type. Using such literals however produces invalid IL that is missing the upcast.

Repro steps

[<Literal>]
let badobj: System.ValueType = 1

System.Console.WriteLine(badobj)

Expected behavior

The code should either succeed and print "1", or it should fail to compile on the basis that badobj is not assigned a constant expression.

Actual behavior

The code compiles fine without any warnings, but generates invalid IL upon retrieving the literal value:

ldc.i4.1
call void [System.Console]System.Console::WriteLine(object)

The box instruction is missing, resulting in System.InvalidProgramException being thrown when the program is launched.

Known workarounds

Avoiding upcasts in constant expressions.

Related information

It seems such a .NET literal is technically valid (the runtime attaches no semantics to the value encoded in the metadata), but it is not CLS-compliant:

CLS Rule 13: The value of a literal static is specified through the use of field initialization metadata (see Partition II Metadata). A CLS-compliant literal must have a value specified in field initialization metadata that is of exactly the same type as the literal (or of the underlying type, if that literal is an enum).

Based on my understanding of the F# specification, it likely should not be possible to define such [<Literal>] values, as upcasting is not mentioned in the list of allowed operations. However, such literals could still be found in imported assemblies compiled from languages that do support them, and thus may be re-referenced in F# code.

This broken literal can also be referenced as a default parameter value:

static member M([<Optional>][<DefaultParameterValue(badobj)>]param: ValueType)

This use seems valid, but also generates invalid IL upon calling the method.

Environment: https://sharplab.io/#v2:DYLgZgzgPg9gDgUwHYAIDKBPCAXBBbAWACh5l0tc8A6AJQFclsBLPBKgSUYQCd40eAbkwDGCCMWIBtADwAZJrm4BDYAD4AusWAJsKAEZKAJjD0ArECgBqKuggAqGRCgC8KAIwSiAYRhIIMbSoAdW4FBHkkBAAKA2MzAEpPbEcEFDsUOFCBJVwo+JdiFBQZADkYHzw4Jm1uTmAmJAaAcw1ClBwckRRWPD0eFABZKJkAeThmXxUNGQARBDAlOmBsAAUlZVZFa2BbGKMTU3iNOHWlPAtt2wdEfNcTjc8fPwC2ELCI6LsqIfj4oA

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Compiler-CodeGenIlxGen, ilwrite and things at the backendBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.

    Type

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions