File: Semantics\ArglistTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Semantic\Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
 
// "__arglist" is an undocumented keyword of the C# language. 
//
// There are three places where __arglist may legally appear in C#. It may appear:
//
// 1) as the final "parameter" of a method declaration:
//
// static void M(int x, int y, __arglist) {}
//
// 2) As an expression in a method whose declaration includes an __arglist parameter:
//
// static void M(int x, int y, __arglist) { var ai = new ArgIterator(__arglist); }
//
// 3) As the "receiver" of a "call" syntax in the last position of a call to an __arglist method:
//
// C.M(1, 2, __arglist(3, 4, 5));
//
// THE FIRST FORM
// ---------------
//
// In its first form it may not appear:
//
// * In a generic method
// * In a generic type
// * In an iterator method declaration
// * In a delegate declaration
// * In a user-defined operator or conversion declaration
//
// UNDONE: We should ensure that __arglist methods may not be async.
//
// In metadata, such a method is referred to as a "varargs" method and is identified
// by the calling convention of the method.
//
// THE SECOND FORM
// ---------------
//
// The second form is a legal expression (almost) anywhere inside a method that includes 
// an __arglist parameter. It is an expression of type System.RuntimeArgumentHandle and 
// classified as a value. It is usually passed to the ctor of the ArgIterator type. 
//
// Speaking of which, we should talk about some special types.
//
// RuntimeArgumentHandle, ArgIterator and TypedReference are "restricted" types:
//
// * A restricted type may not be converted to object.
// * It is illegal to declare a field or property of a restricted type.
// * A restricted type may not be used as a generic type argument.
// * A method or delegate may not return a restricted type.
// * Since a field may not be of a restricted type, a restricted type may not be used 
//   in an anonymous method, lambda or query expression if it would have to be hoisted 
//   to a field.
//
// The native compiler does not consistently enforce these rules. For example,
// it allows:
//
// delegate void D(RuntimeArgumentHandle r);
// static int M(__arglist)
// {
//     D f = null;
//     f = x=>f(__arglist);
// }
//
// Sure enough, C# 5 generates a display class with method:
//
// static int Anonymous(RuntimeArgumentHandle x) { return this.f(__arglist); }
//
// Which doesn't make any sense; the anonymous method is not an __arglist method.
//
// This should simply be illegal; Roslyn disallows __arglist used in the second
// form inside any lambda or anonymous method. (Even if the lambda in question is
// from a query transformation.)
//
// THE THIRD FORM
// --------------
//
// The third form may only appear as the last argument of a call to a varargs method.
//
// UNDONE: The third form may not appear in a method call inside an expression tree lambda.
//
//
// "__reftype" is also an undocumented keyword of C#. It is treated as an operator which
// takes as its sole operand an expression convertible to System.TypedReference. The result is
// the System.Type associated with the type of the typed reference.
//
// "__makeref" is also an undocumented keyword of C#. It is treated as an operator which takes
// as its sole operand an expression classified as a variable. The result is a TypedReference
// to the variable. It is analogous to the "&" address-of operator.
//
// "__refvalue" is also an undocumented keyword of C#. It is badly named, as it has the semantics
// of *dereference to produce a variable*. It is the opposite of the __makeref operator and is
// analogous to the "*" dereference operator. The operator takes a TypedReference and a 
// type, and produces a variable of that type.
//
// 
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    public class ArglistTests : CompilingTestBase
    {
        [Fact]
        public void ExpressionTreeTest()
        {
            var text = @"
using System; 
using System.Linq.Expressions;
public struct C
{
    static void Main()
    {
        Expression<Func<bool>> ex1 = ()=>M(__makeref(S)); // CS7053
        Expression<Func<Type>> ex2 = ()=>__reftype(default(TypedReference));
        Expression<Func<int>> ex3 = ()=>__refvalue(default(TypedReference), int);
        Expression<Func<bool>> ex4 = ()=>N(__arglist());
    }
    static int S = 678;
    public static bool M(TypedReference tr) { return true; }
    public static bool N(__arglist) { return true;}
}";
 
            var comp = CreateCompilationWithMscorlib40AndSystemCore(text);
            comp.VerifyDiagnostics(
// (8,44): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'TypedReference'.
//         Expression<Func<bool>> ex1 = ()=>M(__makeref(S)); // CS7053
Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "__makeref(S)").WithArguments("TypedReference").WithLocation(8, 44),
// (8,44): error CS7053: An expression tree may not contain '__makeref'
//         Expression<Func<bool>> ex1 = ()=>M(__makeref(S)); // CS7053
Diagnostic(ErrorCode.ERR_FeatureNotValidInExpressionTree, "__makeref(S)").WithArguments("__makeref").WithLocation(8, 44),
// (9,42): error CS7053: An expression tree may not contain '__reftype'
//         Expression<Func<Type>> ex2 = ()=>__reftype(default(TypedReference));
Diagnostic(ErrorCode.ERR_FeatureNotValidInExpressionTree, "__reftype(default(TypedReference))").WithArguments("__reftype").WithLocation(9, 42),
// (9,52): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'TypedReference'.
//         Expression<Func<Type>> ex2 = ()=>__reftype(default(TypedReference));
Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default(TypedReference)").WithArguments("TypedReference").WithLocation(9, 52),
// (10,41): error CS7053: An expression tree may not contain '__refvalue'
//         Expression<Func<int>> ex3 = ()=>__refvalue(default(TypedReference), int);
Diagnostic(ErrorCode.ERR_FeatureNotValidInExpressionTree, "__refvalue(default(TypedReference), int)").WithArguments("__refvalue").WithLocation(10, 41),
// (10,52): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'TypedReference'.
//         Expression<Func<int>> ex3 = ()=>__refvalue(default(TypedReference), int);
Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default(TypedReference)").WithArguments("TypedReference").WithLocation(10, 52),
// (11,44): error CS1952: An expression tree lambda may not contain a method with variable arguments
//         Expression<Func<bool>> ex4 = ()=>N(__arglist());
Diagnostic(ErrorCode.ERR_VarArgsInExpressionTree, "__arglist()").WithLocation(11, 44)
                );
        }
 
        [ClrOnlyFact(ClrOnlyReason.Ilasm)]
        public void MakeRefTest01()
        {
            var text = @"
using System;
public struct C
{
    static void Main()
    {
        int i = 1;
        Console.WriteLine(M(__makeref(i)));
    }
    static Type M(TypedReference tr)
    {
        return __reftype(tr);
    }
}";
 
            string expectedIL = @"{
  // Code size       20 (0x14)
  .maxstack  1
  .locals init (int V_0) //i
  IL_0000:  ldc.i4.1
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  mkrefany   ""int""
  IL_0009:  call       ""System.Type C.M(System.TypedReference)""
  IL_000e:  call       ""void System.Console.WriteLine(object)""
  IL_0013:  ret
}";
 
            var verifier = CompileAndVerify(source: text, expectedOutput: "System.Int32", verify: Verification.FailsILVerify);
            verifier.VerifyIL("C.Main", expectedIL);
        }
 
        [Fact]
        public void MakeRefTest02()
        {
            // A makeref is logically the same as passing a variable to a method that takes a ref/out parameter,
            // so we produce the same error messages. This differs from the native compiler, which either fails
            // to produce errors at all, or produces the error messages for a bad assignment. We should not produce
            // errors for bad assignments; first of all, making a ref does not do an assignment, and second, the
            // user might assume that it is the assignment to the local that is bad.
 
            var text = @"
using System;
public struct C
{
    static void Main()
    {
        TypedReference tr1 = default(TypedReference);
        TypedReference tr2 = __makeref(tr1); // CS1601
        TypedReference tr3 = __makeref(123); // CS1510
        TypedReference tr4 = __makeref(P); // CS0206
        TypedReference tr5 = __makeref(R); // CS0199
    }
    static int P { get; set; }
    static readonly int R = 345;
}";
 
            // UNDONE: Test what happens when __makereffing a volatile field, readonly field, etc.
 
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
    // (8,30): error CS1601: Cannot make reference to variable of type 'TypedReference'
    //         TypedReference tr2 = __makeref(tr1); // CS1601
    Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "__makeref(tr1)").WithArguments("System.TypedReference").WithLocation(8, 30),
    // (9,40): error CS1510: A ref or out value must be an assignable variable
    //         TypedReference tr3 = __makeref(123); // CS1510
    Diagnostic(ErrorCode.ERR_RefLvalueExpected, "123").WithLocation(9, 40),
    // (10,40): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
    //         TypedReference tr4 = __makeref(P); // CS0206
    Diagnostic(ErrorCode.ERR_RefProperty, "P").WithLocation(10, 40),
    // (11,40): error CS0199: A static readonly field cannot be used as a ref or out value (except in a static constructor)
    //         TypedReference tr5 = __makeref(R); // CS0199
    Diagnostic(ErrorCode.ERR_RefReadonlyStatic, "R").WithLocation(11, 40)
 
                );
        }
 
        [Fact]
        [WorkItem(23369, "https://github.com/dotnet/roslyn/issues/23369")]
        public void ArglistWithVoidMethod()
        {
            var text = @"
public class C
{
    void M()
    {
        M2(__arglist(1, M()));
    }
    void M2(__arglist)
    {
    }
}";
 
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
                // (6,25): error CS8361: __arglist cannot have an argument of void type
                //         M2(__arglist(1, M()));
                Diagnostic(ErrorCode.ERR_CantUseVoidInArglist, "M()").WithLocation(6, 25)
                );
        }
 
        [Fact]
        public void RefValueUnsafeToReturn()
        {
            var text = @"
using System;
 
class C
{
    private static ref int Test()
    {
        int aa = 42;
        var tr = __makeref(aa);
 
        ref var r = ref Test2(ref __refvalue(tr, int));
 
        return ref r;
    }
 
    private static ref int Test2(ref int r)
    {
        return ref r;
    }
 
    private static ref int Test3(TypedReference tr)
    {
        return ref __refvalue(tr, int);
    }
}";
 
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
                // (13,20): error CS8157: Cannot return 'r' by reference because it was initialized to a value that cannot be returned by reference
                //         return ref r;
                Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r").WithArguments("r").WithLocation(13, 20),
                // (23,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
                //         return ref __refvalue(tr, int);
                Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "__refvalue(tr, int)").WithLocation(23, 20)
 
                );
        }
 
        [Fact]
        public void MakeRefTest03_Dynamic_Bind()
        {
            var text = @"
using System;
public struct C
{
    static void Main()
    {
        dynamic i = 1;
        Console.WriteLine(M(__makeref(i)));
    }
    static Type M(TypedReference tr)
    {
        return __reftype(tr);
    }
}";
 
            CreateCompilation(text).VerifyDiagnostics();
        }
 
        [ClrOnlyFact(ClrOnlyReason.Ilasm)]
        public void RefTypeTest01()
        {
            var text = @"
using System;
using System.Reflection;
public struct C
{
    public string f;
    static void Main()
    {
        Type ctype = typeof(C);
        FieldInfo[] ffield = new FieldInfo[] {ctype.GetFields()[0] };
        TypedReference tr = TypedReference.MakeTypedReference(new C(), ffield);
        Type type = M(tr);
        Console.WriteLine(type.ToString());
    }
    static Type M(TypedReference tr)
    {
        return __reftype(tr);
    }
 
}";
 
            string expectedIL = @"{
  // Code size        9 (0x9)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  refanytype
  IL_0003:  call       ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
  IL_0008:  ret
}";
 
            var verifier = CompileAndVerify(source: text, expectedOutput: "System.String", verify: Verification.FailsILVerify);
            verifier.VerifyIL("C.M", expectedIL);
        }
 
        [Fact]
        public void RefTypeTest02()
        {
            var text = @"
public struct C
{
    static void Main()
    {
        System.Type t = __reftype(null);
    }
}";
 
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
// (6,25): error CS0037: Cannot convert null to 'System.TypedReference' because it is a non-nullable value type
//         System.Type t = __reftype(null);
Diagnostic(ErrorCode.ERR_ValueCantBeNull, "__reftype(null)").WithArguments("System.TypedReference")
                );
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void ArglistTest01()
        {
            var text = @"
using System;
public class C
{
    static void Main()
    {
    }
    
    static void M(__arglist)
    {    
        new ArgIterator(__arglist);
    }
}";
 
            string expectedIL = @"{
  // Code size        9 (0x9)
  .maxstack  1
  IL_0000:  arglist
  IL_0002:  newobj     ""System.ArgIterator..ctor(System.RuntimeArgumentHandle)""
  IL_0007:  pop
  IL_0008:  ret
}";
 
            var verifier = CompileAndVerify(source: text, expectedOutput: "");
            verifier.VerifyIL("C.M(__arglist)", expectedIL);
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void ArglistTest02()
        {
            var text = @"
using System;
public class C
{
    static void Main()
    {
        M(1, __arglist(2, 3, true));
    }
    
    static void M(int x, __arglist)
    {    
        Console.Write(x);
        DumpArgs(new ArgIterator(__arglist));
        new B(4);
        new D(6);
    }
 
    static void DumpArgs(ArgIterator args)
    {
        while(args.GetRemainingCount() > 0)
        {
            TypedReference tr = args.GetNextArg();
            object arg = TypedReference.ToObject(tr);
            Console.Write(arg);
        }
    }
 
    static void M(uint x, __arglist)
    {    
    }
 
    class B
    {
        public B(__arglist)
        {    
            DumpArgs(new ArgIterator(__arglist)); 
        }
        public B(int x) : this(__arglist(x, 5)) {}
    }
    class D : B
    {
        public D(int x) : base(__arglist(x, 7)) {}
    }
 
}";
 
            // Note that this IL is not quite right; here we are displaying the call as "void C.M(int, __arglist)".
            // The actual IL for this program should show the method ref as "void C.M(int, ..., int, int, bool)",
            // because that is the information that is actually encoded in the method ref. If we want to display
            // that then we'll need to add special code to the symbol display visitor that knows how to emit
            // the desired format.
 
            string expectedIL = @"{
  // Code size       10 (0xa)
  .maxstack  4
  IL_0000:  ldc.i4.1
  IL_0001:  ldc.i4.2
  IL_0002:  ldc.i4.3
  IL_0003:  ldc.i4.1
  IL_0004:  call       ""void C.M(int, __arglist) with __arglist( int, int, bool)""
  IL_0009:  ret
}
";
            string expectedOutput = @"123True4567";
            var verifier = CompileAndVerify(source: text, expectedOutput: expectedOutput);
            verifier.VerifyIL("C.Main", expectedIL);
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void ArglistTest03()
        {
            // The native parser produces "type expected" when __arglist is preceded by an illegal
            // modifier. The Roslyn compiler produces the more informative "__arglist not valid" error.
 
            var text = @"
static class C
{
    static void M(int x, __arglist) {}
    static void N(params __arglist) {}
    static void O(ref __arglist) {}
    static void P(out __arglist) {}
    static void Q(this __arglist) {}
    static void Main()
    {
        M(1);
        M(2, 3);
        M(4, 5, 6);
        M(1, __arglist()); // no error
        M(1, __arglist(__arglist()));
        var x = __arglist(123);
    }
    static object R()
    {
        return __arglist(456);
    }
    static void S(int x)
    {
        S(__arglist(1));
    }
    
    [MyAttribute(__arglist(2))]
    static void T() 
    {
        object obj1 = new System.TypedReference();
        object obj2 = (object)new System.ArgIterator();
        // The native compiler produces:
        //'TypedReference' may not be used as a type argument
        // which is not a very descriptive error! There is no type argument here;
        // the fact that anonymous types are actually generic is an implementation detail.
        // Roslyn produces the far more sensible error:
        // cannot assign TypedReference to anonymous type property
        object obj3 = new { X = new System.TypedReference() };
    }
}
 
public class MyAttribute : System.Attribute
{    
  public MyAttribute(__arglist) { }
}
";
 
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
                // (5,26): error CS1669: __arglist is not valid in this context
                //     static void N(params __arglist) {}
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(5, 26),
                // (6,23): error CS1669: __arglist is not valid in this context
                //     static void O(ref __arglist) {}
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(6, 23),
                // (7,23): error CS1669: __arglist is not valid in this context
                //     static void P(out __arglist) {}
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(7, 23),
                // (8,24): error CS1669: __arglist is not valid in this context
                //     static void Q(this __arglist) {}
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(8, 24),
                // (11,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'C.M(int, __arglist)'
                //         M(1);
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "C.M(int, __arglist)").WithLocation(11, 9),
                // (12,14): error CS1503: Argument 2: cannot convert from 'int' to '__arglist'
                //         M(2, 3);
                Diagnostic(ErrorCode.ERR_BadArgType, "3").WithArguments("2", "int", "__arglist").WithLocation(12, 14),
                // (13,9): error CS1501: No overload for method 'M' takes 3 arguments
                //         M(4, 5, 6);
                Diagnostic(ErrorCode.ERR_BadArgCount, "M").WithArguments("M", "3").WithLocation(13, 9),
                // (15,24): error CS0226: An __arglist expression may only appear inside of a call or new expression
                //         M(1, __arglist(__arglist()));
                Diagnostic(ErrorCode.ERR_IllegalArglist, "__arglist()").WithLocation(15, 24),
                // (16,17): error CS0226: An __arglist expression may only appear inside of a call or new expression
                //         var x = __arglist(123);
                Diagnostic(ErrorCode.ERR_IllegalArglist, "__arglist(123)").WithLocation(16, 17),
                // (20,16): error CS0226: An __arglist expression may only appear inside of a call or new expression
                //         return __arglist(456);
                Diagnostic(ErrorCode.ERR_IllegalArglist, "__arglist(456)").WithLocation(20, 16),
                // (24,11): error CS1503: Argument 1: cannot convert from '__arglist' to 'int'
                //         S(__arglist(1));
                Diagnostic(ErrorCode.ERR_BadArgType, "__arglist(1)").WithArguments("1", "__arglist", "int").WithLocation(24, 11),
                // (27,18): error CS0226: An __arglist expression may only appear inside of a call or new expression
                //     [MyAttribute(__arglist(2))]
                Diagnostic(ErrorCode.ERR_IllegalArglist, "__arglist(2)").WithLocation(27, 18),
                // (30,23): error CS0029: Cannot implicitly convert type 'System.TypedReference' to 'object'
                //         object obj1 = new System.TypedReference();
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "new System.TypedReference()").WithArguments("System.TypedReference", "object").WithLocation(30, 23),
                // (31,23): error CS0030: Cannot convert type 'System.ArgIterator' to 'object'
                //         object obj2 = (object)new System.ArgIterator();
                Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object)new System.ArgIterator()").WithArguments("System.ArgIterator", "object").WithLocation(31, 23),
                // (38,29): error CS0828: Cannot assign System.TypedReference to anonymous type property
                //         object obj3 = new { X = new System.TypedReference() };
                Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "X = new System.TypedReference()").WithArguments("System.TypedReference").WithLocation(38, 29));
        }
 
        [Fact]
        public void ArglistTest04()
        {
            var text = @"
using System;
 
class @error
{
    static void Main() {
		Action a = delegate (__arglist) { };
	}
}
";
 
            CreateCompilation(text).VerifyDiagnostics(
                // (7,24): error CS1669: __arglist is not valid in this context
                // 		Action a = delegate (__arglist) { };
                Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist"));
        }
 
        [ClrOnlyFact(ClrOnlyReason.Ilasm)]
        public void RefValueTest01()
        {
            var text = @"
using System;
public struct C
{
    static void Main()
    {
        int i = 1;
        TypedReference tr = __makeref(i);
        Console.Write(i);
        Get(tr);
        Console.Write(i);
        Set(tr, 2);
        Console.Write(i);
        Ref(tr, 3);
        Console.Write(i);
    }
    static int Get(TypedReference tr)
    {
        return __refvalue(tr, int);
    }
    static void Set(TypedReference tr, int i)
    {
        __refvalue(tr, int) = i;
    }
    static void Ref(TypedReference tr, int i)
    {
        // The native compiler generates bad code for this; Roslyn gets it right.
        M(ref __refvalue(tr, int), i);
    }
    static void M(ref int x, int y)
    {
        x = y;
    }
}";
 
            string expectedGetIL = @"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  refanyval  ""int""
  IL_0006:  ldind.i4
  IL_0007:  ret
}";
 
            string expectedSetIL = @"{
  // Code size        9 (0x9)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  refanyval  ""int""
  IL_0006:  ldarg.1
  IL_0007:  stind.i4
  IL_0008:  ret
}";
 
            string expectedRefIL = @"{
  // Code size       13 (0xd)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  refanyval  ""int""
  IL_0006:  ldarg.1
  IL_0007:  call       ""void C.M(ref int, int)""
  IL_000c:  ret
}";
 
            var verifier = CompileAndVerify(source: text, expectedOutput: "1123", verify: Verification.FailsILVerify);
            verifier.VerifyIL("C.Get", expectedGetIL);
            verifier.VerifyIL("C.Set", expectedSetIL);
            verifier.VerifyIL("C.Ref", expectedRefIL);
        }
 
        [ClrOnlyFact(ClrOnlyReason.Ilasm)]
        public void RefValueTest01a()
        {
            var text = @"
using System;
    class Program
    {
        struct S1<T>
        {
            public T x;
 
            public void Assign(T i)
            {
                x = i;
            }
        }
 
        static void Main(string[] args)
        {
            int x = 0;
            var _ref = __makeref(x);
            __refvalue(_ref, int) = 42;
            System.Console.WriteLine(x);
 
            S1<int> s = new S1<int>();
            _ref = __makeref(s);
            __refvalue(_ref, S1<int>).Assign(333);
            System.Console.WriteLine(s.x);
 
            __refvalue(_ref, S1<int>).x = 42;
            System.Console.WriteLine(s.x);
 
            S1<S1<int>> s1 = new S1<S1<int>>();
            _ref = __makeref(s1);
            __refvalue(_ref, S1<S1<int>>).x.Assign(333);
            System.Console.WriteLine(s1.x.x);
 
            __refvalue(_ref, S1<S1<int>>) = default(S1<S1<int>>);
            System.Console.WriteLine(s1.x.x);
 
            __refvalue(_ref, S1<S1<int>>).x.x = 42;
            System.Console.WriteLine(s1.x.x);
 
        }
    }
";
 
            string expectedGetIL = @"
{
  // Code size      202 (0xca)
  .maxstack  3
  .locals init (int V_0, //x
  Program.S1<int> V_1, //s
  Program.S1<Program.S1<int>> V_2) //s1
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  mkrefany   ""int""
  IL_0009:  refanyval  ""int""
  IL_000e:  ldc.i4.s   42
  IL_0010:  stind.i4
  IL_0011:  ldloc.0
  IL_0012:  call       ""void System.Console.WriteLine(int)""
  IL_0017:  ldloca.s   V_1
  IL_0019:  initobj    ""Program.S1<int>""
  IL_001f:  ldloca.s   V_1
  IL_0021:  mkrefany   ""Program.S1<int>""
  IL_0026:  dup
  IL_0027:  refanyval  ""Program.S1<int>""
  IL_002c:  ldc.i4     0x14d
  IL_0031:  call       ""void Program.S1<int>.Assign(int)""
  IL_0036:  ldloc.1
  IL_0037:  ldfld      ""int Program.S1<int>.x""
  IL_003c:  call       ""void System.Console.WriteLine(int)""
  IL_0041:  refanyval  ""Program.S1<int>""
  IL_0046:  ldc.i4.s   42
  IL_0048:  stfld      ""int Program.S1<int>.x""
  IL_004d:  ldloc.1
  IL_004e:  ldfld      ""int Program.S1<int>.x""
  IL_0053:  call       ""void System.Console.WriteLine(int)""
  IL_0058:  ldloca.s   V_2
  IL_005a:  initobj    ""Program.S1<Program.S1<int>>""
  IL_0060:  ldloca.s   V_2
  IL_0062:  mkrefany   ""Program.S1<Program.S1<int>>""
  IL_0067:  dup
  IL_0068:  refanyval  ""Program.S1<Program.S1<int>>""
  IL_006d:  ldflda     ""Program.S1<int> Program.S1<Program.S1<int>>.x""
  IL_0072:  ldc.i4     0x14d
  IL_0077:  call       ""void Program.S1<int>.Assign(int)""
  IL_007c:  ldloc.2
  IL_007d:  ldfld      ""Program.S1<int> Program.S1<Program.S1<int>>.x""
  IL_0082:  ldfld      ""int Program.S1<int>.x""
  IL_0087:  call       ""void System.Console.WriteLine(int)""
  IL_008c:  dup
  IL_008d:  refanyval  ""Program.S1<Program.S1<int>>""
  IL_0092:  initobj    ""Program.S1<Program.S1<int>>""
  IL_0098:  ldloc.2
  IL_0099:  ldfld      ""Program.S1<int> Program.S1<Program.S1<int>>.x""
  IL_009e:  ldfld      ""int Program.S1<int>.x""
  IL_00a3:  call       ""void System.Console.WriteLine(int)""
  IL_00a8:  refanyval  ""Program.S1<Program.S1<int>>""
  IL_00ad:  ldflda     ""Program.S1<int> Program.S1<Program.S1<int>>.x""
  IL_00b2:  ldc.i4.s   42
  IL_00b4:  stfld      ""int Program.S1<int>.x""
  IL_00b9:  ldloc.2
  IL_00ba:  ldfld      ""Program.S1<int> Program.S1<Program.S1<int>>.x""
  IL_00bf:  ldfld      ""int Program.S1<int>.x""
  IL_00c4:  call       ""void System.Console.WriteLine(int)""
  IL_00c9:  ret
}";
 
            var verifier = CompileAndVerify(source: text, expectedOutput: @"42
333
42
333
0
42", verify: Verification.FailsILVerify);
            verifier.VerifyIL("Program.Main", expectedGetIL);
        }
 
        [Fact]
        public void RefValueTest02()
        {
            var text = @"
using System;
static class C
{
    static void Main()
    {
        int a = 1;
        TypedReference tr = __makeref(a);
        int b = __refvalue(123, int);
        int c = __refvalue(tr, Main);
        int d = __refvalue(tr, double);
        __refvalue(tr, int) = null;
    }
}";
 
            // The native compiler produces 
            // CS0118: 'C.Main()' is a 'method' but is used like a 'type'
            // instead of
            // CS0246: The type or namespace name 'Main' could not be found
            // The native compiler behavior seems better here; we might consider fixing Roslyn to match.
 
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
// (9,17): error CS0029: Cannot implicitly convert type 'int' to 'System.TypedReference'
//         int b = __refvalue(123, int);
Diagnostic(ErrorCode.ERR_NoImplicitConv, "__refvalue(123, int)").WithArguments("int", "System.TypedReference"),
 
// (10,32): error CS0246: The type or namespace name 'Main' could not be found (are you missing a using directive or an assembly reference?)
//         int c = __refvalue(tr, Main);
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Main").WithArguments("Main"),
 
// (11,17): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
//         int d = __refvalue(tr, double);
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "__refvalue(tr, double)").WithArguments("double", "int"),
 
// (12,31): error CS0037: Cannot convert null to 'int' because it is a non-nullable value type
//         __refvalue(tr, int) = null;
Diagnostic(ErrorCode.ERR_ValueCantBeNull, "null").WithArguments("int")
);
        }
 
        [Fact]
        public void RefValueTest03_Dynamic_Bind()
        {
            var text = @"
using System;
public struct C
{
    static void Main()
    {
        dynamic i = 1;
        TypedReference tr = __makeref(i);
        Console.Write(i);
        Get(tr);
        Console.Write(i);
        Set(tr, 2);
        Console.Write(i);
    }
    static dynamic Get(TypedReference tr)
    {
        return __refvalue(tr, dynamic);
    }
    static void Set(TypedReference tr, dynamic i)
    {
        __refvalue(tr, dynamic) = i;
    }
}";
 
            CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics();
        }
 
        [ClrOnlyFact(ClrOnlyReason.Ilasm)]
        public void RefValueTest04_optimizer()
        {
            var text = @"
using System;
public struct C
{
    static void Main()
    {
        int k = 42;
 
        int i = 1;
        TypedReference tr1 = __makeref(i);
 
        __refvalue(tr1, int) = k;
        __refvalue(tr1, int) = k;
 
        int j = 1;
        TypedReference tr2 = __makeref(j);
 
        int l = 42;
 
        __refvalue(tr1, int) = l;
        __refvalue(tr2, int) = l;
 
        Console.Write(i);
        Console.Write(j);
    }
}";
 
            var verifier = CompileAndVerify(source: text, expectedOutput: "4242", verify: Verification.FailsILVerify);
            verifier.VerifyIL("C.Main", @"
{
  // Code size       72 (0x48)
  .maxstack  3
  .locals init (int V_0, //k
                int V_1, //i
                System.TypedReference V_2, //tr1
                int V_3, //j
                int V_4) //l
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ldc.i4.1
  IL_0004:  stloc.1
  IL_0005:  ldloca.s   V_1
  IL_0007:  mkrefany   ""int""
  IL_000c:  stloc.2
  IL_000d:  ldloc.2
  IL_000e:  refanyval  ""int""
  IL_0013:  ldloc.0
  IL_0014:  stind.i4
  IL_0015:  ldloc.2
  IL_0016:  refanyval  ""int""
  IL_001b:  ldloc.0
  IL_001c:  stind.i4
  IL_001d:  ldc.i4.1
  IL_001e:  stloc.3
  IL_001f:  ldloca.s   V_3
  IL_0021:  mkrefany   ""int""
  IL_0026:  ldc.i4.s   42
  IL_0028:  stloc.s    V_4
  IL_002a:  ldloc.2
  IL_002b:  refanyval  ""int""
  IL_0030:  ldloc.s    V_4
  IL_0032:  stind.i4
  IL_0033:  refanyval  ""int""
  IL_0038:  ldloc.s    V_4
  IL_003a:  stind.i4
  IL_003b:  ldloc.1
  IL_003c:  call       ""void System.Console.Write(int)""
  IL_0041:  ldloc.3
  IL_0042:  call       ""void System.Console.Write(int)""
  IL_0047:  ret
}
");
        }
 
        [Fact]
        public void TestBug13263()
        {
            var text = @"public class C { public void M() { var t = __makeref(delegate); } }";
            var tree = Parse(text);
            var comp = CreateCompilation(tree);
            var model = comp.GetSemanticModel(tree);
            var root = tree.GetCompilationUnitRoot();
            var clss = root.Members[0] as ClassDeclarationSyntax;
            var meth = clss.Members[0] as MethodDeclarationSyntax;
            var stmt = meth.Body.Statements[0] as LocalDeclarationStatementSyntax;
            var type = stmt.Declaration.Type;
            var info = model.GetSymbolInfo(type);
            Assert.Equal("TypedReference", info.Symbol.Name);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void MethodArgListParameterCount()
        {
            var text = @"
class A
{
    public void M1(__arglist) { }
    public void M2(int x, __arglist) { }
    public void M3(__arglist, int x) { } //illegal, but shouldn't break
    public void M4(__arglist, int x, __arglist) { } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var m1 = type.GetMember<MethodSymbol>("M1");
            Assert.Equal(0, m1.ParameterCount);
            Assert.Equal(0, m1.Parameters.Length);
 
            var m2 = type.GetMember<MethodSymbol>("M2");
            Assert.Equal(1, m2.ParameterCount);
            Assert.Equal(1, m2.Parameters.Length);
 
            var m3 = type.GetMember<MethodSymbol>("M3");
            Assert.Equal(1, m3.ParameterCount);
            Assert.Equal(1, m3.Parameters.Length);
 
            var m4 = type.GetMember<MethodSymbol>("M4");
            Assert.Equal(1, m4.ParameterCount);
            Assert.Equal(1, m4.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ILMethodArgListParameterCount()
        {
            var csharp = @"
class Unused
{
}
";
 
            var il = @"
.class public auto ansi beforefieldinit A
       extends [mscorlib]System.Object
{
  .method public hidebysig instance vararg void 
          M1() cil managed
  {
    ret
  }
 
  .method public hidebysig instance vararg void 
          M2(int32 x) cil managed
  {
    ret
  }
 
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    ldarg.0
    call       instance void [mscorlib]System.Object::.ctor()
    ret
  }
 
} // end of class A
";
 
            var comp = CreateCompilationWithILAndMscorlib40(csharp, il);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var m1 = type.GetMember<MethodSymbol>("M1");
            Assert.Equal(0, m1.ParameterCount);
            Assert.Equal(0, m1.Parameters.Length);
 
            var m2 = type.GetMember<MethodSymbol>("M2");
            Assert.Equal(1, m2.ParameterCount);
            Assert.Equal(1, m2.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void OperatorArgListParameterCount()
        {
            var text = @"
class A
{
    public int operator +(__arglist) { return 0; } //illegal, but shouldn't break
    public int operator -(A a, __arglist) { return 0; } //illegal, but shouldn't break
    public int operator *(__arglist, A a) { return 0; } //illegal, but shouldn't break
    public int operator /(__arglist, A a, __arglist) { return 0; } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var m1 = type.GetMember<MethodSymbol>(WellKnownMemberNames.UnaryPlusOperatorName);
            Assert.Equal(0, m1.ParameterCount);
            Assert.Equal(0, m1.Parameters.Length);
 
            var m2 = type.GetMember<MethodSymbol>(WellKnownMemberNames.SubtractionOperatorName);
            Assert.Equal(1, m2.ParameterCount);
            Assert.Equal(1, m2.Parameters.Length);
 
            var m3 = type.GetMember<MethodSymbol>(WellKnownMemberNames.MultiplyOperatorName);
            Assert.Equal(1, m3.ParameterCount);
            Assert.Equal(1, m3.Parameters.Length);
 
            var m4 = type.GetMember<MethodSymbol>(WellKnownMemberNames.DivisionOperatorName);
            Assert.Equal(1, m4.ParameterCount);
            Assert.Equal(1, m4.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConversionArgListParameterCount1()
        {
            var text = @"
class A
{
    public explicit operator A(__arglist) { return null; } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var conversion = type.GetMember<MethodSymbol>(WellKnownMemberNames.ExplicitConversionName);
            Assert.Equal(0, conversion.ParameterCount);
            Assert.Equal(0, conversion.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConversionArgListParameterCount2()
        {
            var text = @"
class A
{
    public explicit operator A(int x, __arglist) { return null; } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var conversion = type.GetMember<MethodSymbol>(WellKnownMemberNames.ExplicitConversionName);
            Assert.Equal(1, conversion.ParameterCount);
            Assert.Equal(1, conversion.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConversionArgListParameterCount3()
        {
            var text = @"
class A
{
    public explicit operator A(__arglist, A a) { return null; } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var conversion = type.GetMember<MethodSymbol>(WellKnownMemberNames.ExplicitConversionName);
            Assert.Equal(1, conversion.ParameterCount);
            Assert.Equal(1, conversion.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConversionArgListParameterCount4()
        {
            var text = @"
class A
{
    public explicit operator A(__arglist, A a, __arglist) { return null; } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
 
            var conversion = type.GetMember<MethodSymbol>(WellKnownMemberNames.ExplicitConversionName);
            Assert.Equal(1, conversion.ParameterCount);
            Assert.Equal(1, conversion.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConstructorArgListParameterCount1()
        {
            var text = @"
class A
{
    public A(__arglist) { }
}
";
            var comp = CreateCompilation(text);
 
            var constructor = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<MethodSymbol>(WellKnownMemberNames.InstanceConstructorName);
            Assert.Equal(0, constructor.ParameterCount); //doesn't use syntax
            Assert.Equal(0, constructor.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConstructorArgListParameterCount2()
        {
            var text = @"
class A
{
    public A(int x, __arglist) { }
}
";
            var comp = CreateCompilation(text);
 
            var constructor = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<MethodSymbol>(WellKnownMemberNames.InstanceConstructorName);
            Assert.Equal(1, constructor.ParameterCount); //doesn't use syntax
            Assert.Equal(1, constructor.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConstructorArgListParameterCount3()
        {
            var text = @"
class A
{
    public A(__arglist, int x) { } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var constructor = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<MethodSymbol>(WellKnownMemberNames.InstanceConstructorName);
            Assert.Equal(1, constructor.ParameterCount); //doesn't use syntax
            Assert.Equal(1, constructor.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void ConstructorArgListParameterCount4()
        {
            var text = @"
class A
{
    public A(__arglist, int x, __arglist) { } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var constructor = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<MethodSymbol>(WellKnownMemberNames.InstanceConstructorName);
            Assert.Equal(1, constructor.ParameterCount); //doesn't use syntax
            Assert.Equal(1, constructor.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void IndexerArgListParameterCount1()
        {
            var text = @"
class A
{
    public int this[__arglist] { get { return 0; } set { } } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var indexer = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<PropertySymbol>(WellKnownMemberNames.Indexer);
            Assert.Equal(0, indexer.ParameterCount); //doesn't use syntax
            Assert.Equal(0, indexer.Parameters.Length);
 
            var getter = indexer.GetMethod;
            Assert.Equal(0, getter.ParameterCount);
            Assert.Equal(0, getter.Parameters.Length);
 
            var setter = indexer.SetMethod;
            Assert.Equal(1, setter.ParameterCount);
            Assert.Equal(1, setter.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void IndexerArgListParameterCount2()
        {
            var text = @"
class A
{
    public int this[int x, __arglist] { get { return 0; } set { } } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var indexer = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<PropertySymbol>(WellKnownMemberNames.Indexer);
            Assert.Equal(1, indexer.ParameterCount); //doesn't use syntax
            Assert.Equal(1, indexer.Parameters.Length);
 
            var getter = indexer.GetMethod;
            Assert.Equal(1, getter.ParameterCount);
            Assert.Equal(1, getter.Parameters.Length);
 
            var setter = indexer.SetMethod;
            Assert.Equal(2, setter.ParameterCount);
            Assert.Equal(2, setter.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void IndexerArgListParameterCount3()
        {
            var text = @"
class A
{
    public int this[__arglist, int x] { get { return 0; } set { } } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var indexer = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<PropertySymbol>(WellKnownMemberNames.Indexer);
            Assert.Equal(1, indexer.ParameterCount); //doesn't use syntax
            Assert.Equal(1, indexer.Parameters.Length);
 
            var getter = indexer.GetMethod;
            Assert.Equal(1, getter.ParameterCount);
            Assert.Equal(1, getter.Parameters.Length);
 
            var setter = indexer.SetMethod;
            Assert.Equal(2, setter.ParameterCount);
            Assert.Equal(2, setter.Parameters.Length);
        }
 
        [WorkItem(545055, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545055")]
        [WorkItem(545056, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545056")]
        [Fact]
        public void IndexerArgListParameterCount4()
        {
            var text = @"
class A
{
    public int this[__arglist, int x, __arglist] { get { return 0; } set { } } //illegal, but shouldn't break
}
";
            var comp = CreateCompilation(text);
 
            var indexer = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("A").GetMember<PropertySymbol>(WellKnownMemberNames.Indexer);
            Assert.Equal(1, indexer.ParameterCount); //doesn't use syntax
            Assert.Equal(1, indexer.Parameters.Length);
 
            var getter = indexer.GetMethod;
            Assert.Equal(1, getter.ParameterCount);
            Assert.Equal(1, getter.Parameters.Length);
 
            var setter = indexer.SetMethod;
            Assert.Equal(2, setter.ParameterCount);
            Assert.Equal(2, setter.Parameters.Length);
        }
 
        [WorkItem(545086, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545086")]
        [ConditionalFact(typeof(DesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void BoxReceiverTest()
        {
            var text = @"
using System;
class C
{
    static void Goo()
    {
        RuntimeArgumentHandle rah = default(RuntimeArgumentHandle);
        ArgIterator ai = default(ArgIterator);
        TypedReference tr = default(TypedReference);
 
        rah.GetType(); // not virtual
        ai.GetType();  // not virtual
        tr.GetType();  // not virtual
        rah.ToString(); // virtual, overridden on ValueType
        ai.ToString();  // virtual, overridden on ValueType
        tr.ToString();  // virtual, overridden on ValueType
        rah.GetHashCode();  // virtual, overridden on ValueType
        ai.GetHashCode();   // no error: virtual, overridden on ArgIterator
        tr.GetHashCode();   // no error: virtual, overridden on TypedReference
    }
}";
            var comp = CreateCompilation(text);
            comp.VerifyDiagnostics(
// (11,9): error CS0029: Cannot implicitly convert type 'System.RuntimeArgumentHandle' to 'object'
//         rah.GetType(); // not virtual
Diagnostic(ErrorCode.ERR_NoImplicitConv, "rah").WithArguments("System.RuntimeArgumentHandle", "object"),
// (12,9): error CS0029: Cannot implicitly convert type 'System.ArgIterator' to 'object'
//         ai.GetType();  // not virtual
Diagnostic(ErrorCode.ERR_NoImplicitConv, "ai").WithArguments("System.ArgIterator", "object"),
// (13,9): error CS0029: Cannot implicitly convert type 'System.TypedReference' to 'object'
//         tr.GetType();  // not virtual
Diagnostic(ErrorCode.ERR_NoImplicitConv, "tr").WithArguments("System.TypedReference", "object"),
// (14,9): error CS0029: Cannot implicitly convert type 'System.RuntimeArgumentHandle' to 'System.ValueType'
//         rah.ToString(); // virtual, overridden on ValueType
Diagnostic(ErrorCode.ERR_NoImplicitConv, "rah").WithArguments("System.RuntimeArgumentHandle", "System.ValueType"),
// (15,9): error CS0029: Cannot implicitly convert type 'System.ArgIterator' to 'System.ValueType'
//         ai.ToString();  // virtual, overridden on ValueType
Diagnostic(ErrorCode.ERR_NoImplicitConv, "ai").WithArguments("System.ArgIterator", "System.ValueType"),
// (16,9): error CS0029: Cannot implicitly convert type 'System.TypedReference' to 'System.ValueType'
//         tr.ToString();  // virtual, overridden on ValueType
Diagnostic(ErrorCode.ERR_NoImplicitConv, "tr").WithArguments("System.TypedReference", "System.ValueType"),
// (17,9): error CS0029: Cannot implicitly convert type 'System.RuntimeArgumentHandle' to 'System.ValueType'
//         rah.GetHashCode();  // virtual, overridden on ValueType
Diagnostic(ErrorCode.ERR_NoImplicitConv, "rah").WithArguments("System.RuntimeArgumentHandle", "System.ValueType")
                );
        }
 
        [WorkItem(649808, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/649808")]
        [Fact]
        public void MissingArgumentsAndOptionalParameters_1()
        {
            var source =
@"class A
{
    internal A(object x, __arglist) { }
    internal static void M(object x, __arglist) { }
}
class B
{
    internal B(object x = null, __arglist) { }
    internal static void M(object x = null, __arglist) { }
}
class C
{
    internal C(object x, object y = null, __arglist) { }
    internal static void M(object x, object y = null, __arglist) { }
}
class D
{
    internal D(object x = null, object y = null, __arglist) { }
    internal static void M(object x = null, object y = null, __arglist) { }
}
class E
{
    static void M()
    {
        // No optional arguments.
        new A(__arglist());
        new A(null, __arglist());
        A.M(__arglist());
        A.M(null, __arglist());
        // One optional argument.
        new B(__arglist());
        new B(null, __arglist());
        B.M(__arglist());
        B.M(null, __arglist());
        // One required, one optional argument.
        new C(__arglist());
        new C(null, __arglist());
        new C(null, null, __arglist());
        C.M(__arglist());
        C.M(null, __arglist());
        C.M(null, null, __arglist());
        // Two optional arguments.
        new D(__arglist());
        new D(null, __arglist());
        new D(null, null, __arglist());
        D.M(__arglist());
        D.M(null, __arglist());
        D.M(null, null, __arglist());
    }
}";
            CreateCompilation(source).VerifyDiagnostics(
                // (26,13): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'A.A(object, __arglist)'
                //         new A(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "A").WithArguments("__arglist", "A.A(object, __arglist)").WithLocation(26, 13),
                // (28,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'A.M(object, __arglist)'
                //         A.M(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "A.M(object, __arglist)").WithLocation(28, 11),
                // (31,13): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'B.B(object, __arglist)'
                //         new B(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "B").WithArguments("__arglist", "B.B(object, __arglist)").WithLocation(31, 13),
                // (33,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'B.M(object, __arglist)'
                //         B.M(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "B.M(object, __arglist)").WithLocation(33, 11),
                // (36,13): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'C.C(object, object, __arglist)'
                //         new C(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "C").WithArguments("__arglist", "C.C(object, object, __arglist)").WithLocation(36, 13),
                // (37,13): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'C.C(object, object, __arglist)'
                //         new C(null, __arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "C").WithArguments("__arglist", "C.C(object, object, __arglist)").WithLocation(37, 13),
                // (39,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'C.M(object, object, __arglist)'
                //         C.M(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "C.M(object, object, __arglist)").WithLocation(39, 11),
                // (40,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'C.M(object, object, __arglist)'
                //         C.M(null, __arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "C.M(object, object, __arglist)").WithLocation(40, 11),
                // (43,13): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'D.D(object, object, __arglist)'
                //         new D(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "D").WithArguments("__arglist", "D.D(object, object, __arglist)").WithLocation(43, 13),
                // (44,13): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'D.D(object, object, __arglist)'
                //         new D(null, __arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "D").WithArguments("__arglist", "D.D(object, object, __arglist)").WithLocation(44, 13),
                // (46,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'D.M(object, object, __arglist)'
                //         D.M(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "D.M(object, object, __arglist)").WithLocation(46, 11),
                // (47,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'D.M(object, object, __arglist)'
                //         D.M(null, __arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("__arglist", "D.M(object, object, __arglist)").WithLocation(47, 11));
        }
 
        [WorkItem(649808, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/649808")]
        [Fact]
        public void MissingArgumentsAndOptionalParameters_2()
        {
            var ilSource =
@".class public sealed D extends [mscorlib]System.MulticastDelegate
{
  .method public hidebysig specialname rtspecialname instance void .ctor(object o, native int m) runtime { }
  .method public hidebysig instance vararg void Invoke([opt] object o) runtime { }
  .method public hidebysig instance class [mscorlib]System.IAsyncResult BeginInvoke(class [mscorlib]System.AsyncCallback c, object o) runtime { }
  .method public hidebysig instance void EndInvoke(class [mscorlib]System.IAsyncResult r) runtime { }
}";
            var source =
@"class C
{
    static void M(D d)
    {
        d(null, __arglist());
        d(__arglist());
    }
}";
            var compilation = CreateCompilationWithILAndMscorlib40(source, ilSource);
            compilation.VerifyDiagnostics(
                // (6,9): error CS7036: There is no argument given that corresponds to the required parameter '__arglist' of 'D'
                //         d(__arglist());
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "d").WithArguments("__arglist", "D").WithLocation(6, 9));
        }
 
        [Fact, WorkItem(1253, "https://github.com/dotnet/roslyn/issues/1253")]
        public void LambdaWithUnsafeParameter()
        {
            var source =
@"
 
using System;
using System.Threading;
 
namespace ConsoleApplication21
{
    public unsafe class GooBar : IDisposable
    {
        public void Dispose()
        {
            NativeOverlapped* overlapped = AllocateNativeOverlapped(() => { });
        }
 
        private unsafe static NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object context, byte[] pinData)
        {
            return null;
        }
    }
}
";
            CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
    // (12,44): error CS7036: There is no argument given that corresponds to the required parameter 'context' of 'GooBar.AllocateNativeOverlapped(IOCompletionCallback, object, byte[])'
    //             NativeOverlapped* overlapped = AllocateNativeOverlapped(() => { });
    Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "AllocateNativeOverlapped").WithArguments("context", "ConsoleApplication21.GooBar.AllocateNativeOverlapped(System.Threading.IOCompletionCallback, object, byte[])").WithLocation(12, 44)
);
        }
 
        [Fact, WorkItem(8152, "https://github.com/dotnet/roslyn/issues/8152")]
        public void DuplicateDeclaration()
        {
            var source =
@"
public class SpecialCases
{
    public void ArgListMethod(__arglist)
    {
        ArgListMethod(__arglist(""""));
    }
    public void ArgListMethod(__arglist)
    {
        ArgListMethod(__arglist(""""));
    }
}
";
            CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
    // (8,17): error CS0111: Type 'SpecialCases' already defines a member called 'ArgListMethod' with the same parameter types
    //     public void ArgListMethod(__arglist)
    Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "ArgListMethod").WithArguments("ArgListMethod", "SpecialCases").WithLocation(8, 17),
    // (6,9): error CS0121: The call is ambiguous between the following methods or properties: 'SpecialCases.ArgListMethod(__arglist)' and 'SpecialCases.ArgListMethod(__arglist)'
    //         ArgListMethod(__arglist(""));
    Diagnostic(ErrorCode.ERR_AmbigCall, "ArgListMethod").WithArguments("SpecialCases.ArgListMethod(__arglist)", "SpecialCases.ArgListMethod(__arglist)").WithLocation(6, 9),
    // (10,9): error CS0121: The call is ambiguous between the following methods or properties: 'SpecialCases.ArgListMethod(__arglist)' and 'SpecialCases.ArgListMethod(__arglist)'
    //         ArgListMethod(__arglist(""));
    Diagnostic(ErrorCode.ERR_AmbigCall, "ArgListMethod").WithArguments("SpecialCases.ArgListMethod(__arglist)", "SpecialCases.ArgListMethod(__arglist)").WithLocation(10, 9)
                );
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void ArgListMayNotHaveAnOutArgument()
        {
            CreateCompilation(@"
class Program
{
    static void Test(__arglist)
    {
        var a = 1;
    	Test(__arglist(out a));
    }
}
").VerifyDiagnostics(
                // (7,25): error CS8378: __arglist cannot have an argument passed by 'in' or 'out'
                //     	Test(__arglist(out a));
                Diagnostic(ErrorCode.ERR_CantUseInOrOutInArglist, "a").WithLocation(7, 25));
        }
 
        [Fact]
        public void ArgListMayNotHaveAnInArgument()
        {
            CreateCompilation(@"
class Program
{
    static void Test(__arglist)
    {
        var a = 1;
    	Test(__arglist(in a));
    }
}
").VerifyDiagnostics(
                // (7,24): error CS8378: __arglist cannot have an argument passed by 'in' or 'out'
                //     	Test(__arglist(in a));
                Diagnostic(ErrorCode.ERR_CantUseInOrOutInArglist, "a").WithLocation(7, 24));
        }
 
        [ConditionalFact(typeof(WindowsDesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void ArgListMayHaveARefArgument()
        {
            CompileAndVerify(@"
using System;
class Program
{
    static void Test(__arglist)
    {
        var args = new ArgIterator(__arglist);
        ref int a = ref __refvalue(args.GetNextArg(), int);
        a = 5;
    }
    static void Main()
    {
        int a = 0;
        Test(__arglist(ref a));
        Console.WriteLine(a);
    }
}",
                options: TestOptions.DebugExe,
                expectedOutput: "5");
        }
 
        [ConditionalFact(typeof(DesktopOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        public void ArgListMayHaveAByValArgument()
        {
            CompileAndVerify(@"
using System;
class Program
{
    static void Test(__arglist)
    {
        var args = new ArgIterator(__arglist);
        int a = __refvalue(args.GetNextArg(), int);
        Console.WriteLine(a);
    }
    static void Main()
    {
        int a = 5;
        Test(__arglist(a));
    }
}",
                options: TestOptions.DebugExe,
                expectedOutput: "5");
        }
 
        [ConditionalTheory(typeof(WindowsOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        [CombinatorialData]
        public void RefModifier([CombinatorialValues("ref", "in")] string modifier)
        {
            var source = $$"""
                class C
                {
                    static void M({{modifier}} int x, __arglist) => System.Console.Write(x);
 
                    static void Main()
                    {
                        int x = 111;
                        M({{modifier}} x, __arglist(x));
                    }
                }
                """;
            CompileAndVerify(source, expectedOutput: "111", verify: Verification.FailsILVerify).VerifyDiagnostics();
        }
 
        [ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.RestrictedTypesNeedDesktop)]
        [WorkItem("https://github.com/dotnet/roslyn/issues/68714")]
        public void InAsRValue()
        {
            var source = """
                class C
                {
                    static void M(in int x, __arglist) => System.Console.Write(x);
 
                    static void Main()
                    {
                        int x = 111;
                        M(x, __arglist(x));
                    }
                }
                """;
            CompileAndVerify(source, expectedOutput: "111", verify: Verification.FailsILVerify).VerifyDiagnostics();
        }
    }
}