Roslyn: VS 15.5 Preview: VerificationException in otherwise valid function

Created on 16 Oct 2017  路  7Comments  路  Source: dotnet/roslyn

Version Used:
Microsoft Visual Studio Enterprise 2017 Preview
Version 15.5.0 Preview 1.0

Steps to Reproduce:

  1. Create a .NET Framework Console Application
  2. Replace the contents of Program.cs with the code below.
  3. Run the program.

Expected Behavior:

The program prints "Comparison: 0"

Actual Behavior:

The program crashes with a VerificationException in StructyMcStructFace.CompareTo.

VerificationException

Code:

using System;
using System.Security;

[assembly: AllowPartiallyTrustedCallers()]

namespace RoslynRepro155
{
    class Program
    {
        static void Main(string[] args)
        {
            var color1 = new StructyMcStructFace(TColorType.Automatic);
            var color2 = new StructyMcStructFace(TColorType.Automatic);

            var result = color1.CompareTo(color2);
            Console.WriteLine("Comparison: {0}", result);
            Console.ReadKey();
        }
    }

    public enum TAutomaticColor
    {
    }

    public enum TColorType
    {
        Automatic,
        RGB,
        Theme,
        Indexed
    }

    public struct StructyMcStructFace
    {
        public StructyMcStructFace(TColorType type)
        {
            ColorType = type;
            automaticType = default(TAutomaticColor);

        }

        readonly TAutomaticColor automaticType;

        public TColorType ColorType { get; }

        public int CompareTo(StructyMcStructFace other)
        {
            switch (ColorType)
            {
                case TColorType.Automatic:
                    return automaticType.CompareTo(other.automaticType);
            }

            return 0;
        }
    }
}

IL of CompareTo with Visual Studio 2017 v15.4.0:

.method public hidebysig 
    instance int32 CompareTo (
        valuetype RoslynRepro155.StructyMcStructFace other
    ) cil managed 
{
    // Method begins at RVA 0x20b0
    // Code size 53 (0x35)
    .maxstack 2
    .locals init (
        [0] valuetype RoslynRepro155.TColorType,
        [1] valuetype RoslynRepro155.TAutomaticColor,
        [2] int32
    )

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: call instance valuetype RoslynRepro155.TColorType RoslynRepro155.StructyMcStructFace::get_ColorType()
    IL_0007: stloc.0
    IL_0008: ldloc.0
    IL_0009: brfalse.s IL_000d

    IL_000b: br.s IL_002f

    IL_000d: ldarg.0
    IL_000e: ldfld valuetype RoslynRepro155.TAutomaticColor RoslynRepro155.StructyMcStructFace::automaticType
    IL_0013: stloc.1
    IL_0014: ldloca.s 1
    IL_0016: ldarg.1
    IL_0017: ldfld valuetype RoslynRepro155.TAutomaticColor RoslynRepro155.StructyMcStructFace::automaticType
    IL_001c: box RoslynRepro155.TAutomaticColor
    IL_0021: constrained. RoslynRepro155.TAutomaticColor
    IL_0027: callvirt instance int32 [mscorlib]System.Enum::CompareTo(object)
    IL_002c: stloc.2
    IL_002d: br.s IL_0033

    IL_002f: ldc.i4.0
    IL_0030: stloc.2
    IL_0031: br.s IL_0033

    IL_0033: ldloc.2
    IL_0034: ret
} // end of method StructyMcStructFace::CompareTo

IL of CompareTo with Visual Studio 2017 v15.5.0 Preview:

.method public hidebysig 
    instance int32 CompareTo (
        valuetype RoslynRepro155.StructyMcStructFace other
    ) cil managed 
{
    // Method begins at RVA 0x20b0
    // Code size 50 (0x32)
    .maxstack 2
    .locals init (
        [0] valuetype RoslynRepro155.TColorType,
        [1] int32
    )

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: call instance valuetype RoslynRepro155.TColorType RoslynRepro155.StructyMcStructFace::get_ColorType()
    IL_0007: stloc.0
    IL_0008: ldloc.0
    IL_0009: brfalse.s IL_000d

    IL_000b: br.s IL_002c

    IL_000d: ldarg.0
    IL_000e: ldflda valuetype RoslynRepro155.TAutomaticColor RoslynRepro155.StructyMcStructFace::automaticType
    IL_0013: ldarg.1
    IL_0014: ldfld valuetype RoslynRepro155.TAutomaticColor RoslynRepro155.StructyMcStructFace::automaticType
    IL_0019: box RoslynRepro155.TAutomaticColor
    IL_001e: constrained. RoslynRepro155.TAutomaticColor
    IL_0024: callvirt instance int32 [mscorlib]System.Enum::CompareTo(object)
    IL_0029: stloc.1
    IL_002a: br.s IL_0030

    IL_002c: ldc.i4.0
    IL_002d: stloc.1
    IL_002e: br.s IL_0030

    IL_0030: ldloc.1
    IL_0031: ret
} // end of method StructyMcStructFace::CompareTo
Area-Compilers

Most helpful comment

This seems to be similar to https://github.com/dotnet/roslyn/issues/22485, except here it's not just PEVerify complaining, it's also the runtime, due to the presence of AllowPartiallyTrustedCallers. And the workaround mentioned there does work: adding <Features>peverify-compat</Features> to csproj makes the code work for me in VS 15.5 Preview 1.

All 7 comments

Tagging @gafter @TyOverby

This seems to be similar to https://github.com/dotnet/roslyn/issues/22485, except here it's not just PEVerify complaining, it's also the runtime, due to the presence of AllowPartiallyTrustedCallers. And the workaround mentioned there does work: adding <Features>peverify-compat</Features> to csproj makes the code work for me in VS 15.5 Preview 1.

Tagging @VSadov. We should probably update the breaking changes doc and give a one-liner there (relates to https://github.com/dotnet/roslyn/pull/21269).

We could also check for things like AllowPartiallyTrustedCallers or security transparent and disable the optimizations that go beyond verification rules on desktop.

logged https://github.com/dotnet/roslyn/issues/22712

At least for APTCA, it seems possible and reasonable to sniff for the attribute and enable compat mode automatically. Same might be true for SecurityTransparent

@VSadov Good to close?

Yes. we have short term a solution that we believe is the right balance between desire to use new features and produce code compatible with old verification rules: https://github.com/dotnet/roslyn/pull/22772

We are also working on extending verification rules:
https://github.com/dotnet/designs/pull/17
https://github.com/dotnet/designs/pull/21

Was this page helpful?
0 / 5 - 0 ratings