PageRenderTime 49ms CodeModel.GetById 4ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 1ms

/Src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs

https://github.com/EkardNT/Roslyn
C# | 7065 lines | 6589 code | 370 blank | 106 comment | 117 complexity | 65b60a20701d305e57ea57ce19e17487 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
   2
   3using System.Collections.Generic;
   4using System.Linq;
   5using System.Threading;
   6using Microsoft.CodeAnalysis.CSharp.Symbols;
   7using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
   8using Microsoft.CodeAnalysis.Test.Utilities;
   9using Roslyn.Test.Utilities;
  10using Roslyn.Utilities;
  11using Xunit;
  12
  13namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
  14{
  15    public class CodeGenAsyncTests : EmitMetadataTestBase
  16    {
  17        private CSharpCompilation CreateCompilation(string source, IEnumerable<MetadataReference> references = null, CSharpCompilationOptions compOptions = null)
  18        {
  19            SynchronizationContext.SetSynchronizationContext(null);
  20
  21            compOptions = compOptions ?? TestOptions.OptimizedExe;
  22
  23            IEnumerable<MetadataReference> asyncRefs = new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef };
  24            references = (references != null) ? references.Concat(asyncRefs) : asyncRefs;
  25
  26            return CreateCompilationWithMscorlib45(source, compOptions: compOptions, references: references);
  27        }
  28
  29        private CompilationVerifier CompileAndVerify(string source, string expectedOutput, IEnumerable<MetadataReference> references = null, EmitOptions emitOptions = EmitOptions.All, CSharpCompilationOptions compOptions = null, bool emitPdb = false)
  30        {
  31            SynchronizationContext.SetSynchronizationContext(null);
  32
  33            var compilation = this.CreateCompilation(source, references: references, compOptions: compOptions);
  34            return base.CompileAndVerify(compilation, expectedOutput: expectedOutput, emitOptions: emitOptions, emitPdb: emitPdb);
  35        }
  36
  37        [Fact]
  38        public void StructVsClass()
  39        {
  40            var source = @"
  41using System.Threading;
  42using System.Threading.Tasks;
  43
  44class Test
  45{
  46    public static async Task F(int a)
  47    {
  48        await Task.Factory.StartNew(() => { System.Console.WriteLine(a); });
  49    }
  50
  51    public static void Main()
  52    {   
  53        F(123).Wait();
  54    }
  55}";
  56            var c = CreateCompilationWithMscorlib45(source);
  57
  58            CompilationOptions options;
  59
  60            options = TestOptions.OptimizedExe;
  61            Assert.False(options.EnableEditAndContinue);
  62
  63            CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  64            {
  65                var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  66                Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  67            }, expectedOutput: "123");
  68
  69            options = TestOptions.UnoptimizedExe;
  70            Assert.False(options.EnableEditAndContinue);
  71
  72            CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  73            {
  74                var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  75                Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  76            }, expectedOutput: "123");
  77
  78            options = TestOptions.OptimizedExe.WithDebugInformationKind(DebugInformationKind.Full);
  79            Assert.False(options.EnableEditAndContinue);
  80
  81            CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  82            {
  83                var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  84                Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  85            }, expectedOutput: "123");
  86
  87            options = TestOptions.UnoptimizedExe.WithDebugInformationKind(DebugInformationKind.PdbOnly);
  88            Assert.False(options.EnableEditAndContinue);
  89
  90            CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  91            {
  92                var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  93                Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  94            }, expectedOutput: "123");
  95
  96            options = TestOptions.UnoptimizedExe.WithDebugInformationKind(DebugInformationKind.Full);
  97            Assert.True(options.EnableEditAndContinue);
  98
  99            CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
 100            {
 101                var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
 102                Assert.Equal(TypeKind.Class, stateMachine.TypeKind);
 103            }, expectedOutput: "123");
 104        }
 105
 106        [Fact]
 107        public void VoidReturningAsync()
 108        {
 109            var source = @"
 110using System;
 111using System.Diagnostics;
 112using System.Threading;
 113using System.Threading.Tasks;
 114
 115class Test
 116{
 117    static int i = 0;
 118
 119    public static async void F(AutoResetEvent handle)
 120    {
 121        try
 122        {
 123            await Task.Factory.StartNew(() =>
 124            {
 125                Interlocked.Increment(ref Test.i);
 126            });
 127        }
 128        finally
 129        {
 130            handle.Set();
 131        }
 132    }
 133
 134    public static void Main()
 135    {
 136        var handle = new AutoResetEvent(false);
 137        F(handle);
 138        handle.WaitOne(1000 * 60);
 139        Console.WriteLine(i);
 140    }
 141}";
 142            var expected = @"
 1431
 144";
 145            CompileAndVerify(source, expectedOutput: expected);
 146        }
 147
 148        [Fact]
 149        [WorkItem(624970, "DevDiv")]
 150        public void AsyncWithEH()
 151        {
 152            var source = @"
 153using System;
 154using System.Diagnostics;
 155using System.Threading;
 156using System.Threading.Tasks;
 157
 158class Test
 159{
 160    static int awaitCount = 0;
 161    static int finallyCount = 0;
 162
 163    static void LogAwait()
 164    {
 165        Interlocked.Increment(ref awaitCount);
 166    }
 167
 168    static void LogException()
 169    {
 170        Interlocked.Increment(ref finallyCount);
 171    }
 172
 173    public static async void F(AutoResetEvent handle)
 174    {
 175        try
 176        {
 177            await Task.Factory.StartNew(LogAwait);
 178            try
 179            {
 180                await Task.Factory.StartNew(LogAwait);
 181                try
 182                {
 183                    await Task.Factory.StartNew(LogAwait);
 184                    try
 185                    {
 186                        await Task.Factory.StartNew(LogAwait);
 187                        throw new Exception();
 188                    }
 189                    catch (Exception)
 190                    {
 191                    }
 192                    finally
 193                    {
 194                        LogException();
 195                    }
 196                    await Task.Factory.StartNew(LogAwait);
 197                    throw new Exception();
 198                }
 199                catch (Exception)
 200                {
 201                }
 202                finally
 203                {
 204                    LogException();
 205                }
 206                await Task.Factory.StartNew(LogAwait);
 207                throw new Exception();
 208            }
 209            catch (Exception)
 210            {
 211            }
 212            finally
 213            {
 214                LogException();
 215            }
 216            await Task.Factory.StartNew(LogAwait);
 217        }
 218        finally
 219        {
 220            handle.Set();
 221        }
 222    }
 223
 224    public static void Main2(int i)
 225    {
 226        try
 227        {
 228            awaitCount = 0;
 229            finallyCount = 0;
 230            var handle = new AutoResetEvent(false);
 231            F(handle);
 232            var completed = handle.WaitOne(1000 * 60);
 233            if (completed)
 234            {
 235                if (awaitCount != 7 || finallyCount != 3)
 236                {
 237                    throw new Exception(""failed at i="" + i);
 238                }
 239            }
 240            else
 241            {
 242                Console.WriteLine(""Test did not complete in time."");
 243            }
 244        }
 245        catch (Exception ex)
 246        {
 247            Console.WriteLine(""unexpected exception thrown:"");
 248            Console.WriteLine(ex.ToString());
 249        }
 250    }
 251
 252    public static void Main()
 253    {
 254        for (int i = 0; i < 1500; i++)
 255        {
 256            Main2(i);
 257        }
 258    }
 259}";
 260            var expected = @"";
 261            CompileAndVerify(source, expectedOutput: expected);
 262        }
 263
 264        [Fact, WorkItem(855080, "DevDiv")]
 265        public void GenericCatchVariableInAsyncMethod()
 266        {
 267            var source = @"
 268using System;
 269using System.Collections.Generic;
 270using System.Linq;
 271using System.Text;
 272using System.Threading.Tasks;
 273namespace ConsoleApplication1
 274{
 275    class Program
 276    {
 277        static void Main(string[] args)
 278        {
 279            Console.WriteLine(Bar().Result);
 280        }
 281        static async Task<int> Bar()
 282        {
 283            NotImplementedException ex = await Foo<NotImplementedException>();
 284            return 3;
 285        }
 286        public static async Task<T> Foo<T>() where T : Exception
 287        {
 288            Task<int> task = null;
 289            if (task != null) await task;
 290            T result = null;
 291            try
 292            {
 293            }
 294            catch (T ex)
 295            {
 296                result = ex;
 297            }
 298            return result;
 299        }
 300    }
 301}
 302";
 303            CompileAndVerify(source, expectedOutput: "3");
 304        }
 305
 306        [Fact]
 307        public void TaskReturningAsync()
 308        {
 309            var source = @"
 310using System;
 311using System.Diagnostics;
 312using System.Threading.Tasks;
 313
 314class Test
 315{
 316    static int i = 0;
 317
 318    public static async Task F()
 319    {
 320        await Task.Factory.StartNew(() =>
 321        {
 322            Test.i = 42;
 323        });
 324    }
 325
 326    public static void Main()
 327    {
 328        Task t = F();
 329        t.Wait(1000 * 60);
 330        Console.WriteLine(Test.i);
 331    }
 332}";
 333            var expected = @"
 33442
 335";
 336            CompileAndVerify(source, expectedOutput: expected);
 337        }
 338
 339        [Fact]
 340        public void GenericTaskReturningAsync()
 341        {
 342            var source = @"
 343using System;
 344using System.Diagnostics;
 345using System.Threading.Tasks;
 346
 347class Test
 348{
 349    public static async Task<string> F()
 350    {
 351        return await Task.Factory.StartNew(() => { return ""O brave new world...""; });
 352    }
 353
 354    public static void Main()
 355    {
 356        Task<string> t = F();
 357        t.Wait(1000 * 60);
 358        Console.WriteLine(t.Result);
 359    }
 360}";
 361            var expected = @"
 362O brave new world...
 363";
 364            CompileAndVerify(source, expectedOutput: expected);
 365        }
 366
 367        [Fact]
 368        public void AsyncWithLocals()
 369        {
 370            var source = @"
 371using System;
 372using System.Threading.Tasks;
 373
 374class Test
 375{
 376    public static async Task<int> F(int x)
 377    {
 378        return await Task.Factory.StartNew(() => { return x; });
 379    }
 380
 381    public static async Task<int> G(int x)
 382    {
 383        int c = 0;
 384        await F(x);
 385        c += x;
 386        await F(x);
 387        c += x;
 388        return c;
 389    }
 390
 391    public static void Main()
 392    {
 393        Task<int> t = G(21);
 394        t.Wait(1000 * 60);
 395        Console.WriteLine(t.Result);
 396    }
 397}";
 398            var expected = @"
 39942
 400";
 401            CompileAndVerify(source, expectedOutput: expected);
 402        }
 403
 404        [Fact]
 405        public void AsyncWithTernary()
 406        {
 407            var source = @"
 408using System;
 409using System.Threading.Tasks;
 410
 411class Test
 412{
 413    public static Task<T> F<T>(T x)
 414    {
 415        Console.WriteLine(""F("" + x + "")"");
 416        return Task.Factory.StartNew(() => { return x; });
 417    }
 418
 419    public static async Task<int> G(bool b1, bool b2)
 420    {
 421        int c = 0;
 422        c = c + (b1 ? 1 : await F(2));
 423        c = c + (b2 ? await F(4) : 8);
 424        return await F(c);
 425    }
 426
 427    public static int H(bool b1, bool b2)
 428    {
 429        Task<int> t = G(b1, b2);
 430        t.Wait(1000 * 60);
 431        return t.Result;
 432    }
 433
 434    public static void Main()
 435    {
 436        Console.WriteLine(H(false, false));
 437        Console.WriteLine(H(false, true));
 438        Console.WriteLine(H(true, false));
 439        Console.WriteLine(H(true, true));
 440    }
 441}";
 442            var expected = @"
 443F(2)
 444F(10)
 44510
 446F(2)
 447F(4)
 448F(6)
 4496
 450F(9)
 4519
 452F(4)
 453F(5)
 4545
 455";
 456            CompileAndVerify(source, expectedOutput: expected);
 457        }
 458
 459        [Fact]
 460        public void AsyncWithAnd()
 461        {
 462            var source = @"
 463using System;
 464using System.Threading.Tasks;
 465
 466class Test
 467{
 468    public static Task<T> F<T>(T x)
 469    {
 470        Console.WriteLine(""F("" + x + "")"");
 471        return Task.Factory.StartNew(() => { return x; });
 472    }
 473
 474    public static async Task<int> G(bool b1, bool b2)
 475    {
 476        bool x1 = b1 && await F(true);
 477        bool x2 = b1 && await F(false);
 478        bool x3 = b2 && await F(true);
 479        bool x4 = b2 && await F(false);
 480        int c = 0;
 481        if (x1) c += 1;
 482        if (x2) c += 2;
 483        if (x3) c += 4;
 484        if (x4) c += 8;
 485        return await F(c);
 486    }
 487
 488    public static int H(bool b1, bool b2)
 489    {
 490        Task<int> t = G(b1, b2);
 491        t.Wait(1000 * 60);
 492        return t.Result;
 493    }
 494
 495    public static void Main()
 496    {
 497        Console.WriteLine(H(false, true));
 498    }
 499}";
 500            var expected = @"
 501F(True)
 502F(False)
 503F(4)
 5044
 505";
 506            CompileAndVerify(source, expectedOutput: expected);
 507        }
 508
 509        [Fact]
 510        public void AsyncWithOr()
 511        {
 512            var source = @"
 513using System;
 514using System.Threading.Tasks;
 515
 516class Test
 517{
 518    public static Task<T> F<T>(T x)
 519    {
 520        Console.WriteLine(""F("" + x + "")"");
 521        return Task.Factory.StartNew(() => { return x; });
 522    }
 523
 524    public static async Task<int> G(bool b1, bool b2)
 525    {
 526        bool x1 = b1 || await F(true);
 527        bool x2 = b1 || await F(false);
 528        bool x3 = b2 || await F(true);
 529        bool x4 = b2 || await F(false);
 530        int c = 0;
 531        if (x1) c += 1;
 532        if (x2) c += 2;
 533        if (x3) c += 4;
 534        if (x4) c += 8;
 535        return await F(c);
 536    }
 537
 538    public static int H(bool b1, bool b2)
 539    {
 540        Task<int> t = G(b1, b2);
 541        t.Wait(1000 * 60);
 542        return t.Result;
 543    }
 544
 545    public static void Main()
 546    {
 547        Console.WriteLine(H(false, true));
 548    }
 549}";
 550            var expected = @"
 551F(True)
 552F(False)
 553F(13)
 55413
 555";
 556            CompileAndVerify(source, expectedOutput: expected);
 557        }
 558
 559        [Fact]
 560        public void AsyncWithCoalesce()
 561        {
 562            var source = @"
 563using System;
 564using System.Threading.Tasks;
 565
 566class Test
 567{
 568    public static Task<string> F(string x)
 569    {
 570        Console.WriteLine(""F("" + (x ?? ""null"") + "")"");
 571        return Task.Factory.StartNew(() => { return x; });
 572    }
 573
 574    public static async Task<string> G(string s1, string s2)
 575    {
 576        var result = await F(s1) ?? await F(s2);
 577        Console.WriteLine("" "" + (result ?? ""null""));
 578        return result;
 579    }
 580
 581    public static string H(string s1, string s2)
 582    {
 583        Task<string> t = G(s1, s2);
 584        t.Wait(1000 * 60);
 585        return t.Result;
 586    }
 587
 588    public static void Main()
 589    {
 590        H(null, null);
 591        H(null, ""a"");
 592        H(""b"", null);
 593        H(""c"", ""d"");
 594    }
 595}";
 596            var expected = @"
 597F(null)
 598F(null)
 599 null
 600F(null)
 601F(a)
 602 a
 603F(b)
 604 b
 605F(c)
 606 c
 607";
 608            CompileAndVerify(source, expectedOutput: expected);
 609        }
 610
 611        [Fact]
 612        public void AsyncWithParam()
 613        {
 614            var source = @"
 615using System;
 616using System.Threading.Tasks;
 617
 618class Test
 619{
 620    public static async Task<int> G(int x)
 621    {
 622        await Task.Factory.StartNew(() => { return x; });
 623        x += 21;
 624        await Task.Factory.StartNew(() => { return x; });
 625        x += 21;
 626        return x;
 627    }
 628
 629    public static void Main()
 630    {
 631        Task<int> t = G(0);
 632        t.Wait(1000 * 60);
 633        Console.WriteLine(t.Result);
 634    }
 635}";
 636            var expected = @"
 63742
 638";
 639            CompileAndVerify(source, expectedOutput: expected);
 640        }
 641
 642        [Fact]
 643        public void AwaitInExpr()
 644        {
 645            var source = @"
 646using System;
 647using System.Threading.Tasks;
 648
 649class Test
 650{
 651    public static async Task<int> F()
 652    {
 653        return await Task.Factory.StartNew(() => 21);
 654    }
 655
 656    public static async Task<int> G()
 657    {
 658        int c = 0;
 659        c = (await F()) + 21;
 660        return c;
 661    }
 662
 663    public static void Main()
 664    {
 665        Task<int> t = G();
 666        t.Wait(1000 * 60);
 667        Console.WriteLine(t.Result);
 668    }
 669}";
 670            var expected = @"
 67142
 672";
 673            CompileAndVerify(source, expectedOutput: expected);
 674        }
 675
 676        [Fact]
 677        public void AsyncWithParamsAndLocals_UnHoisted()
 678        {
 679            var source = @"
 680using System;
 681using System.Threading.Tasks;
 682
 683class Test
 684{
 685    public static async Task<int> F(int x)
 686    {
 687        return await Task.Factory.StartNew(() => { return x; });
 688    }
 689
 690    public static async Task<int> G(int x)
 691    {
 692        int c = 0;
 693        c = await F(x);
 694        return c;
 695    }
 696
 697    public static void Main()
 698    {
 699        Task<int> t = G(21);
 700        t.Wait(1000 * 60);
 701        Console.WriteLine(t.Result);
 702    }
 703}";
 704            var expected = @"
 70521
 706";
 707            CompileAndVerify(source, expectedOutput: expected);
 708        }
 709
 710        [Fact]
 711        public void AsyncWithParamsAndLocals_Hoisted()
 712        {
 713            var source = @"
 714using System;
 715using System.Threading.Tasks;
 716
 717class Test
 718{
 719    public static async Task<int> F(int x)
 720    {
 721        return await Task.Factory.StartNew(() => { return x; });
 722    }
 723
 724    public static async Task<int> G(int x)
 725    {
 726        int c = 0;
 727        c = await F(x);
 728        return c;
 729    }
 730
 731    public static void Main()
 732    {
 733        Task<int> t = G(21);
 734        t.Wait(1000 * 60);
 735        Console.WriteLine(t.Result);
 736    }
 737}";
 738            var expected = @"
 73921
 740";
 741            CompileAndVerify(source, expectedOutput: expected);
 742        }
 743
 744        [Fact]
 745        public void AsyncWithParamsAndLocals_DoubleAwait_Spilling()
 746        {
 747            var source = @"
 748using System;
 749using System.Threading.Tasks;
 750
 751class Test
 752{
 753    public static async Task<int> F(int x)
 754    {
 755        return await Task.Factory.StartNew(() => { return x; });
 756    }
 757
 758    public static async Task<int> G(int x)
 759    {
 760        int c = 0;
 761        c = (await F(x)) + c;
 762        c = (await F(x)) + c;
 763        return c;
 764    }
 765
 766    public static void Main()
 767    {
 768        Task<int> t = G(21);
 769        t.Wait(1000 * 60);
 770        Console.WriteLine(t.Result);
 771    }
 772}";
 773            var expected = @"
 77442
 775";
 776            // When the local 'c' gets hoisted, the statement:
 777            //   c = (await F(x)) + c;
 778            // Gets rewritten to:
 779            //   this.c_field = (await F(x)) + this.c_field;
 780            //
 781            // The code-gen for the assignment is something like this:
 782            //   ldarg0  // load the 'this' reference to the stack
 783            //   <emitted await expression>
 784            //   stfld
 785            //
 786            // What we really want is to evaluate any parts of the lvalue that have side-effects (which is this case is
 787            // nothing), and then defer loading the address for the field reference until after the await expression:
 788            //   <emitted await expression>
 789            //   <store to tmp>
 790            //   ldarg0
 791            //   <load tmp>
 792            //   stfld
 793            //
 794            // So this case actually requires stack spilling, which is not yet implemented. This has the unfortunate
 795            // consequence of preventing await expressions from being assigned to hoisted locals.
 796            //
 797            CompileAndVerify(source, expectedOutput: expected);
 798        }
 799
 800        [Fact]
 801        public void AsyncWithDynamic()
 802        {
 803            var source = @"
 804using System;
 805using System.Threading.Tasks;
 806
 807class Test
 808{
 809    public static async Task<int> F(dynamic t)
 810    {
 811        return await t;
 812    }
 813
 814    public static void Main()
 815    {
 816        Task<int> t = F(Task.Factory.StartNew(() => { return 42; }));
 817        t.Wait(1000 * 60);
 818        Console.WriteLine(t.Result);
 819    }
 820}";
 821            var expected = @"
 82242
 823";
 824            CompileAndVerify(source, expectedOutput: expected, references: new[] { CSharpRef });
 825        }
 826
 827        [Fact]
 828        public void AsyncWithThisRef()
 829        {
 830            var source = @"
 831using System;
 832using System.Threading.Tasks;
 833
 834class C
 835{
 836    int x = 42;
 837
 838    public async Task<int> F()
 839    {
 840        int c = this.x;
 841        return await Task.Factory.StartNew(() => c);
 842    }
 843}
 844
 845class Test
 846{
 847    public static void Main()
 848    {
 849        Task<int> t = new C().F();
 850        t.Wait(1000 * 60);
 851        Console.WriteLine(t.Result);
 852    }
 853}";
 854            var expected = @"
 85542
 856";
 857            CompileAndVerify(source, expectedOutput: expected);
 858        }
 859
 860        [Fact]
 861        public void AsyncWithBaseRef()
 862        {
 863            var source = @"
 864using System;
 865using System.Threading.Tasks;
 866
 867class B
 868{
 869    protected int x = 42;   
 870}
 871
 872class C : B
 873{
 874    public async Task<int> F()
 875    {
 876        int c = base.x;
 877        return await Task.Factory.StartNew(() => c);
 878    }
 879}
 880
 881class Test
 882{
 883    public static void Main()
 884    {
 885        Task<int> t = new C().F();
 886        t.Wait(1000 * 60);
 887        Console.WriteLine(t.Result);
 888    }
 889}";
 890            var expected = @"
 89142
 892";
 893            CompileAndVerify(source, expectedOutput: expected);
 894        }
 895
 896        [Fact]
 897        public void AsyncWithException1()
 898        {
 899            var source = @"
 900using System;
 901using System.Threading.Tasks;
 902
 903class Test
 904{
 905    static async Task<int> F()
 906    {
 907        throw new Exception();
 908    }
 909
 910    static async Task<int> G()
 911    {
 912        try
 913        {
 914            return await F();
 915        }
 916        catch(Exception)
 917        {
 918            return -1;
 919        }
 920    }
 921
 922    public static void Main()
 923    {
 924        Task<int> t2 = G();
 925        t2.Wait(1000 * 60);
 926        Console.WriteLine(t2.Result);
 927    }
 928}";
 929            var expected = @"
 930-1
 931";
 932            CompileAndVerify(source, expectedOutput: expected);
 933        }
 934
 935        [Fact]
 936        public void AsyncWithException2()
 937        {
 938            var source = @"
 939using System;
 940using System.Threading.Tasks;
 941
 942class Test
 943{
 944    static async Task<int> F()
 945    {
 946        throw new Exception();
 947    }
 948
 949    static async Task<int> H()
 950    {
 951        return await F();
 952    }
 953
 954    public static void Main()
 955    {
 956        Task<int> t1 = H();
 957        try
 958        {
 959            t1.Wait(1000 * 60);
 960        }
 961        catch (AggregateException)
 962        {
 963            Console.WriteLine(""exception"");
 964        }
 965    }
 966}";
 967            var expected = @"
 968exception
 969";
 970            CompileAndVerify(source, expectedOutput: expected);
 971        }
 972
 973        [Fact]
 974        public void AsyncInFinally001()
 975        {
 976            var source = @"
 977using System;
 978using System.Threading.Tasks;
 979
 980class Test
 981{
 982    static async Task<int> F()
 983    {
 984        return 2;
 985    }
 986
 987    static async Task<int> G()
 988    {
 989        int x = 42;
 990
 991        try
 992        {
 993        }
 994        finally
 995        {
 996            x = await F();
 997        }
 998
 999        return x;
1000    }
1001
1002    public static void Main()
1003    {
1004        Task<int> t2 = G();
1005        t2.Wait(1000 * 60);
1006        Console.WriteLine(t2.Result);
1007    }
1008}";
1009            var expected = @"
10102
1011";
1012            CompileAndVerify(source, expectedOutput: expected).
1013VerifyIL("Test.<G>d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
1014{
1015  // Code size      229 (0xe5)
1016  .maxstack  3
1017  .locals init (int V_0,
1018  int V_1,
1019  object V_2,
1020  System.Runtime.CompilerServices.TaskAwaiter<int> V_3,
1021  object V_4,
1022  System.Exception V_5)
1023  IL_0000:  ldarg.0
1024  IL_0001:  ldfld      ""int Test.<G>d__1.<>1__state""
1025  IL_0006:  stloc.0
1026  .try
1027{
1028  IL_0007:  ldloc.0
1029  IL_0008:  brfalse.s  IL_000e
1030  IL_000a:  ldloc.0
1031  IL_000b:  ldc.i4.1
1032  IL_000c:  beq.s      IL_005f
1033  IL_000e:  ldarg.0
1034  IL_000f:  ldnull
1035  IL_0010:  stfld      ""object Test.<G>d__1.<>7__wrap1""
1036  IL_0015:  ldarg.0
1037  IL_0016:  ldc.i4.0
1038  IL_0017:  stfld      ""int Test.<G>d__1.<>7__wrap2""
1039  .try
1040{
1041  IL_001c:  leave.s    IL_0028
1042}
1043  catch object
1044{
1045  IL_001e:  stloc.2
1046  IL_001f:  ldarg.0
1047  IL_0020:  ldloc.2
1048  IL_0021:  stfld      ""object Test.<G>d__1.<>7__wrap1""
1049  IL_0026:  leave.s    IL_0028
1050}
1051  IL_0028:  call       ""System.Threading.Tasks.Task<int> Test.F()""
1052  IL_002d:  callvirt   ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
1053  IL_0032:  stloc.3
1054  IL_0033:  ldloca.s   V_3
1055  IL_0035:  call       ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
1056  IL_003a:  brtrue.s   IL_007b
1057  IL_003c:  ldarg.0
1058  IL_003d:  ldc.i4.1
1059  IL_003e:  dup
1060  IL_003f:  stloc.0
1061  IL_0040:  stfld      ""int Test.<G>d__1.<>1__state""
1062  IL_0045:  ldarg.0
1063  IL_0046:  ldloc.3
1064  IL_0047:  stfld      ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
1065  IL_004c:  ldarg.0
1066  IL_004d:  ldflda     ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
1067  IL_0052:  ldloca.s   V_3
1068  IL_0054:  ldarg.0
1069  IL_0055:  call       ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Test.<G>d__1>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Test.<G>d__1)""
1070  IL_005a:  leave      IL_00e4
1071  IL_005f:  ldarg.0
1072  IL_0060:  ldfld      ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
1073  IL_0065:  stloc.3
1074  IL_0066:  ldarg.0
1075  IL_0067:  ldflda     ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
1076  IL_006c:  initobj    ""System.Runtime.CompilerServices.TaskAwaiter<int>""
1077  IL_0072:  ldarg.0
1078  IL_0073:  ldc.i4.m1
1079  IL_0074:  dup
1080  IL_0075:  stloc.0
1081  IL_0076:  stfld      ""int Test.<G>d__1.<>1__state""
1082  IL_007b:  ldloca.s   V_3
1083  IL_007d:  call       ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
1084  IL_0082:  ldloca.s   V_3
1085  IL_0084:  initobj    ""System.Runtime.CompilerServices.TaskAwaiter<int>""
1086  IL_008a:  ldarg.0
1087  IL_008b:  ldfld      ""object Test.<G>d__1.<>7__wrap1""
1088  IL_0090:  stloc.s    V_4
1089  IL_0092:  ldloc.s    V_4
1090  IL_0094:  brfalse.s  IL_00ad
1091  IL_0096:  ldloc.s    V_4
1092  IL_0098:  isinst     ""System.Exception""
1093  IL_009d:  dup
1094  IL_009e:  brtrue.s   IL_00a3
1095  IL_00a0:  ldloc.s    V_4
1096  IL_00a2:  throw
1097  IL_00a3:  call       ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)""
1098  IL_00a8:  callvirt   ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()""
1099  IL_00ad:  ldarg.0
1100  IL_00ae:  ldnull
1101  IL_00af:  stfld      ""object Test.<G>d__1.<>7__wrap1""
1102  IL_00b4:  stloc.1
1103  IL_00b5:  leave.s    IL_00d0
1104}
1105  catch System.Exception
1106{
1107  IL_00b7:  stloc.s    V_5
1108  IL_00b9:  ldarg.0
1109  IL_00ba:  ldc.i4.s   -2
1110  IL_00bc:  stfld      ""int Test.<G>d__1.<>1__state""
1111  IL_00c1:  ldarg.0
1112  IL_00c2:  ldflda     ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
1113  IL_00c7:  ldloc.s    V_5
1114  IL_00c9:  call       ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
1115  IL_00ce:  leave.s    IL_00e4
1116}
1117  IL_00d0:  ldarg.0
1118  IL_00d1:  ldc.i4.s   -2
1119  IL_00d3:  stfld      ""int Test.<G>d__1.<>1__state""
1120  IL_00d8:  ldarg.0
1121  IL_00d9:  ldflda     ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
1122  IL_00de:  ldloc.1
1123  IL_00df:  call       ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
1124  IL_00e4:  ret
1125}
1126");
1127        }
1128
1129        [Fact]
1130        public void AsyncInFinally002()
1131        {
1132            var source = @"
1133using System;
1134using System.Threading.Tasks;
1135
1136class Test
1137{
1138    static async Task<int> F()
1139    {
1140        System.Console.Write(""F"");
1141        return 2;
1142    }
1143
1144    static async Task G()
1145    {
1146        int x = 0;
1147
1148        try
1149        {
1150            throw new Exception(""hello"");
1151        }
1152        finally
1153        {
1154            x += await F();
1155        }
1156    }
1157
1158    public static void Main()
1159    {
1160        Task t2 = G();
1161        try
1162        {
1163            t2.Wait(1000 * 60);
1164        }
1165        catch (Exception ex)
1166        {
1167            Console.WriteLine(ex.Message);
1168        }
1169    }
1170}";
1171            var expected = @"FOne or more errors occurred.
1172";
1173            CompileAndVerify(source, expectedOutput: expected);
1174        }
1175
1176        [Fact]
1177        public void AsyncInFinally003()
1178        {
1179            var source = @"
1180using System;
1181using System.Threading.Tasks;
1182
1183class Test
1184{
1185    static async Task<int> F()
1186    {
1187        return 2;
1188    }
1189
1190    static async Task<int> G()
1191    {
1192        int x = 0;
1193
1194        try
1195        {
1196            x = await F();
1197            return x;
1198        }
1199        finally
1200        {
1201            x += await F();
1202        }
1203    }
1204
1205    public static void Main()
1206    {
1207        Task<int> t2 = G();
1208        t2.Wait(1000 * 60);
1209        Console.WriteLine(t2.Result);
1210    }
1211}";
1212            var expected = @"
12132
1214";
1215            CompileAndVerify(source, expectedOutput: expected);
1216        }
1217
1218        [Fact]
1219        public void AsyncInFinally004()
1220        {
1221            var source = @"
1222using System;
1223using System.Threading.Tasks;
1224
1225class Test
1226{
1227    static async Task<int> F()
1228    {
1229        return 2;
1230    }
1231
1232    static async Task<int> G()
1233    {
1234        int x = 0;
1235
1236        try
1237        {
1238            try
1239            {
1240                throw new Exception();
1241            }
1242            finally
1243            {
1244                x += await F();
1245            }
1246        }
1247        catch
1248        {
1249            return x;
1250        }
1251    }
1252
1253    public static void Main()
1254    {
1255        Task<int> t2 = G();
1256        t2.Wait(1000 * 60);
1257        Console.WriteLine(t2.Result);
1258    }
1259}";
1260            var expected = @"
12612
1262";
1263            CompileAndVerify(source, expectedOutput: expected);
1264        }
1265
1266        [Fact]
1267        public void AsyncInFinallyNested001()
1268        {
1269            var source = @"
1270using System;
1271using System.Threading.Tasks;
1272
1273class Test
1274{
1275    static async Task<int> F(int a)
1276    {
1277        await Task.Yield();
1278        return a;
1279    }
1280
1281    static async Task<int> G()
1282    {
1283        int x = 0;
1284
1285        try
1286        {
1287            try
1288            {
1289                x = await F(1);
1290                goto L1;
1291                System.Console.WriteLine(""FAIL"");
1292            }
1293            finally
1294            {
1295                x += await F(2);
1296            }
1297        }
1298        finally
1299        {
1300            try
1301            {
1302                x += await F(4);
1303            }
1304            finally
1305            {
1306                x += await F(8);
1307            }
1308        }
1309
1310        System.Console.WriteLine(""FAIL"");
1311
1312        L1:
1313        return x;
1314    }
1315
1316    public static void Main()
1317    {
1318        Task<int> t2 = G();
1319        t2.Wait(1000 * 60);
1320        Console.WriteLine(t2.Result);
1321    }
1322}";
1323            var expected = @"15";
1324            CompileAndVerify(source, expectedOutput: expected);
1325        }
1326
1327        [Fact]
1328        public void AsyncInFinallyNested002()
1329        {
1330            var source = @"
1331using System;
1332using System.Threading.Tasks;
1333
1334class Test
1335{
1336    static async Task<int> F(int a)
1337    {
1338        await Task.Yield();
1339        return a;
1340    }
1341
1342    static async Task<int> G()
1343    {
1344        int x = 0;
1345
1346        try
1347        {
1348            try
1349            {
1350                try
1351                {
1352                    x = await F(1);
1353                    throw new Exception(""hello"");
1354                    System.Console.WriteLine(""FAIL"");
1355                }
1356                finally
1357                {
1358                    x += await F(2);
1359                }
1360
1361                System.Console.WriteLine(""FAIL"");
1362            }
1363            finally
1364            {
1365                try
1366                {
1367                    x += await F(4);
1368                }
1369                finally
1370                {
1371                    x += await F(8);
1372                }
1373            }
1374
1375            System.Console.WriteLine(""FAIL"");
1376        }
1377        catch(Exception ex)
1378        {
1379            System.Console.WriteLine(ex.Message);
1380        }      
1381
1382        return x;
1383    }
1384
1385    public static void Main()
1386    {
1387        Task<int> t2 = G();
1388        t2.Wait(1000 * 60);
1389        Console.WriteLine(t2.Result);
1390    }
1391}";
1392            var expected = @"hello
139315";
1394            CompileAndVerify(source, expectedOutput: expected);
1395        }
1396
1397        [Fact]
1398        public void AsyncInFinallyNested003()
1399        {
1400            var source = @"
1401using System;
1402using System.Threading.Tasks;
1403
1404class Test
1405{
1406    static async Task<int> F(int a)
1407    {
1408        await Task.Yield();
1409        return a;
1410    }
1411
1412    static async Task<int> G()
1413    {
1414        int x = 0;
1415
1416        try
1417        {
1418            try
1419            {
1420                try
1421                {
1422                    x = await F(1);
1423                    throw new Exception(""hello"");
1424                    System.Console.WriteLine(""FAIL"");
1425                }
1426                finally
1427                {
1428                    x += await F(2);
1429                }
1430
1431                System.Console.WriteLine(""FAIL"");
1432            }
1433            finally
1434            {
1435                try
1436                {
1437                    x += await F(4);
1438                }
1439                finally
1440                {
1441                    x += await F(8);
1442                    throw new Exception(""bye"");
1443                }
1444            }
1445
1446            System.Console.WriteLine(""FAIL"");
1447        }
1448        catch(Exception ex)
1449        {
1450            System.Console.WriteLine(ex.Message);
1451        }      
1452
1453        return x;
1454    }
1455
1456    public static void Main()
1457    {
1458        Task<int> t2 = G();
1459        t2.Wait(1000 * 60);
1460        Console.WriteLine(t2.Result);
1461    }
1462}";
1463            var expected = @"bye
146415";
1465            CompileAndVerify(source, expectedOutput: expected);
1466        }
1467
1468        [Fact]
1469        public void AsyncInCatch001()
1470        {
1471            var source = @"
1472using System;
1473using System.Threading.Tasks;
1474
1475class Test
1476{
1477    static async Task<int> F()
1478    {
1479        return 2;
1480    }
1481
1482    static async Task<int> G()
1483    {
1484        int x = 0;
1485
1486        try
1487        {
1488            x = x / x;
1489        }
1490        catch
1491        {
1492            x = await F();
1493        }
1494
1495        return x;
1496    }
1497
1498    public static void Main()
1499    {
1500        Task<int> t2 = G();
1501        t2.Wait(1000 * 60);
1502        Console.WriteLine(t2.Result);
1503    }
1504}";
1505            var expected = @"
15062
1507";
1508            CompileAndVerify(source, expectedOutput: expected).
1509VerifyIL("Test.<G>d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
1510{
1511  // Code size      182 (0xb6)
1512  .maxstack  3
1513  .locals init (int V_0,
1514  int V_1, 
1515  int V_2, //x
1516  int V_3,
1517  System.Runtime.CompilerServices.TaskAwaiter<int> V_4,
1518  System.Exception V_5)
1519  IL_0000:  ldarg.0
1520  IL_0001:  ldfld      ""int Test.<G>d__1.<>1__state""
1521  IL_0006:  stloc.0
1522  .try
1523{
1524  IL_0007:  ldloc.0
1525  IL_0008:  brfalse.s  IL_000e
1526  IL_000a:  ldloc.0
1527  IL_000b:  ldc.i4.1
1528  IL_000c:  beq.s      IL_0057
1529  IL_000e:  ldc.i4.0
1530  IL_000f:  stloc.2
1531  IL_0010:  ldc.i4.0
1532  IL_0011:  stloc.3
1533  .try
1534{
1535  IL_0012:  ldloc.2
1536  IL_0013:  dup
1537  IL_0014:  div
1538  IL_0015:  stloc.2
1539  IL_0016:  leave.s    IL_001d
1540}
1541  catch object
1542{
1543  IL_0018:  pop
1544  IL_0019:  ldc.i4.1
1545  IL_001a:  stloc.3
1546  IL_001b:  leave.s    IL_001d
1547}
1548  IL_001d:  ldloc.3
1549  IL_001e:  ldc.i4.1
1550  IL_001f:  bne.un.s   IL_0084
1551  IL_0021:  call       ""System.Threading.Tasks.Task<int> Test.F()""
1552  IL_0026:  callvirt   ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
1553  IL_002b:  stloc.s    V_4
1554  IL_002d:  ldloca.s   V_4
1555  IL_002f:  call       ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
1556  IL_0034:  brtrue.s   IL_0074
1557  IL_0036:  ldarg.0
1558  IL_0037:  ldc.i4.1
1559  IL_0038:  dup
1560  IL_0039:  stloc.0
1561  IL_003a:  stfld      ""int Test.<G>d__1.<>1__state""
1562  IL_003f:  ldarg.0
1563  IL_0040:  ldloc.s    V_4
1564  IL_0042:  stfld      ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
1565  IL_0047:  ldarg.0
1566  IL_0048:  ldflda     ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
1567  IL_004d:  ldloca.s   V_4
1568  IL_004f:  ldarg.0
1569  IL_0050:  call       ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Test.<G>d__1>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Test.<G>d__1)""
1570  IL_0055:  leave.s    IL_00b5
1571  IL_0057:  ldarg.0
1572  IL_0058:  ldfld      ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
1573  IL_005d:  stloc.s    V_4
1574  IL_005f:  ldarg.0
1575  IL_0060:  ldflda     ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
1576  IL_0065:  initobj    ""System.Runtime.CompilerServices.TaskAwaiter<int>""
1577  IL_006b:  ldarg.0
1578  IL_006c:  ldc.i4.m1
1579  IL_006d:  dup
1580  IL_006e:  stloc.0
1581  IL_006f:  stfld      ""int Test.<G>d__1.<>1__state""
1582  IL_0074:  ldloca.s   V_4
1583  IL_0076:  call       ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
1584  IL_007b:  ldloca.s   V_4
1585  IL_007d:  initobj    ""System.Runtime.CompilerServices.TaskAwaiter<int>""
1586  IL_0083:  stloc.2
1587  IL_0084:  ldloc.2
1588  IL_0085:  stloc.1
1589  IL_0086:  leave.s    IL_00a1
1590}
1591  catch System.Exception
1592{
1593  IL_0088:  stloc.s    V_5
1594  IL_008a:  ldarg.0
1595  IL_008b:  ldc.i4.s   -2
1596  IL_008d:  stfld      ""int Test.<G>d__1.<>1__state""
1597  IL_0092:  ldarg.0
1598  IL_0093:  ldflda     ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
1599  IL_0098:  ldloc.s    V_5
1600  IL_009a:  call       ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
1601  IL_009f:  leave.s    IL_00b5
1602}
1603  IL_00a1:  ldarg.0
1604  IL_00a2:  ldc.i4.s   -2
1605  IL_00a4:  stfld      ""int Test.<G>d__1.<>1__state""
1606  IL_00a9:  ldarg.0
1607  IL_00aa:  ldflda     ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
1608  IL_00af:  ldloc.1
1609  IL_00b0:  call       ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
1610  IL_00b5:  ret
1611}
1612");
1613        }
1614
1615        [Fact]
1616        public void AsyncInCatchRethrow()
1617        {
1618            var source = @"
1619using System;
1620using System.Threading.Tasks;
1621
1622class Test
1623{
1624    static async Task<int> F()
1625    {
1626        await Task.Yield();
1627        return 2;
1628    }
1629
1630    static async Task<int> G()
1631    {
1632        int x = 0;
1633
1634        try
1635        {
1636            try
1637            {
1638                x = x / x;
1639            }
1640            catch
1641            {
1642                x = await F();
1643                throw;
1644            }
1645        }
1646        catch(DivideByZeroException ex)
1647        {
1648            x = await F();
1649            System.Console.WriteLine(ex.Message);
1650        }
1651
1652        return x;
1653    }
1654
1655    public static void Main()
1656    {
1657        Task<int> t2 = G();
1658        t2.Wait(1000 * 60);
1659        Console.WriteLine(t2.Result);
1660    }
1661}";
1662            var expected = @"
1663Attempted to divide by zero.
16642
1665";
1666            CompileAndVerify(source, expectedOutput: expected);
1667        }
1668
1669        [Fact]
1670        public void AsyncInCatchFilter()
1671        {
1672            var source = @"
1673using System;
1674using System.Threading.Tasks;
1675
1676class Test
1677{
1678    static async Task<int> F()
1679    {
1680        await Task.Yield();
1681        return 2;
1682    }
1683
1684    static async Task<int> G()
1685    {
1686        int x = 0;
1687
1688        try
1689        {
1690            try
1691            {
1692                x = x / x;
1693            }
1694            catch if(x != 0)
1695            {
1696                x = await F();
1697                throw;
1698            }
1699        }
1700        catch(Exception ex) if(x == 0 && ((ex = new Exception(""hello"")) != null))
1701        {
1702            x = await F();
1703            System.Console.WriteLine(ex.Message);
1704        }
1705
1706        return x;
1707    }
1708
1709    public static void Main()
1710    {
1711        Task<int> t2 = G();
1712        t2.Wait(1000 * 60);
1713        Console.WriteLine(t2.Result);
1714    }
1715}";
1716            var expected = @"
1717hello
17182
1719";
1720            CompileAndVerify(source, expectedOutput: expected);
1721        }
1722
1723        [Fact]
1724        public void AsyncInCatchFilterLifted()
1725        {
1726            var source = @"
1727using System;
1728using System.Threading.Tasks;
1729
1730class Test
1731{
1732    static async Task<int> F()
1733    {
1734        await Task.Yield();
1735        return 2;
1736    }
1737
1738    static bool T(Func<bool> f, ref Exception ex)
1739    {
1740        var result = f();
1741        ex = new Exception(result.ToString());
1742        return result;
1743    }
1744
1745    static async Task<int> G()
1746    {
1747        int x = 0;
1748
1749        try
1750        {
1751            x = x / x;
1752        }
1753        catch(Exception ex) if(T(()=>ex.Message == null, ref ex))
1754        {
1755            x = await F();
1756            System.Console.WriteLine(ex.Message);
1757        }
1758        catch(Exception ex) if(T(()=>ex.Message != null, ref ex))
1759        {
1760            x = await F();
1761            System.Console.WriteLine(ex.Message);
1762        }
1763        return x;
1764    }
1765
1766    public static void Main()
1767    {
1768        Task<int> t2 = G();
1769        t2.Wait(1000 * 60);
1770        Console.WriteLine(t2.Result);
1771    }
1772}";
1773            var expected = @"True
17742
1775";
1776            CompileAndVerify(source, expectedOutput: expected);
1777        }
1778
1779        [Fact]
1780        public void AsyncInCatchFinallyMixed()
1781        {
1782            var source = @"
1783using System;
1784using System.Threading.Tasks;
1785
1786class Test
1787{
1788    static async Task<int> F(int x)
1789    {
1790        await Task.Yield();
1791        return x;
1792    }
1793
1794    static async Task<int> G()
1795    {
1796        int x = 0;
1797
1798        try
1799        {
1800            try
1801            {
1802                for (int i = 0; i < 5; i++)
1803                {
1804                    try
1805                    {
1806                        try
1807                        {
1808                            x = x / await F(0);
1809                        }
1810                        catch (DivideByZeroException) if (i < 3)
1811                        {
1812                            await Task.Yield();
1813                            continue;
1814                        }
1815                        catch (DivideByZeroException)
1816                        {
1817                            x = 2 + await F(x);
1818                            throw;
1819                        }
1820                        System.Console.WriteLine(""FAIL"");
1821                    }
1822                    finally
1823                    {
1824                        x = await F(x) + 3;
1825                        if (i >= 3)
1826                        {
1827                            throw new Exception(""hello"");
1828                        }
1829                    }
1830                }
1831            }
1832            finally
1833            {
1834                x = 11 + await F(x);
1835            }
1836        }
1837        catch (Exception ex)
1838        {
1839            x = await F(x) + 17;
1840            System.Console.WriteLine(ex.Message);
1841        }
1842
1843        return x;
1844    }
1845
1846    public static void Main()
1847    {
1848        Task<int> t2 = G();
1849        t2.Wait(1000 * 60);
1850        Console.WriteLine(t2.Result);
1851    }
1852}";
1853            var expected = @"
1854hello
185542
1856";
1857            CompileAndVerify(source, expectedOutput: expected);
1858        }
1859
1860        [Fact]
1861        public void AsyncInCatchFinallyMixed_InAsyncLambda()
1862        {
1863            var source = @"
1864using System;
1865using System.Threading.Tasks;
1866
1867class Test
1868{
1869    static async Task<int> F(int x)
1870    {
1871        await Task.Yield();
1872        return x;
1873    }
1874
1875    static Func<Task<int>> G()
1876    {
1877        int x = 0;
1878
1879        return async () =>
1880        {
1881            try
1882            {
1883                try
1884                {
1885                    for (int i = 0; i < 5; i++)
1886                    {
1887                        try
1888                        {
1889                            try
1890                            {
1891                                x = x / await F(0);
1892                            }
1893                            catch (DivideByZeroException) if (i < 3)
1894                            {
1895                                await Task.Yield();
1896                                continue;
1897                            }
1898                            catch (DivideByZeroException)
1899                            {
1900                                x = 2 + await F(x);
1901                                throw;
1902                            }
1903                            System.Console.WriteLine(""FAIL"");
1904                        }
1905                        finally
1906                        {
1907                            x = await F(x) + 3;
1908                            if (i >= 3)
1909                            {
1910                                throw new Exception(""hello"");
1911                            }
1912                        }
1913                    }
1914                }
1915                finally
1916                {
1917                    x = 11 + await F(x);
1918                }
1919            }
1920            catch (Exception ex)
1921            {
1922                x = await F(x) + 17;
1923                System.Console.WriteLine(ex.Message);
1924            }
1925
1926            return x;
1927        };
1928    }
1929
1930    public static void Main()
1931    {
1932        Task<int> t2 = G()();
1933        t2.Wait(1000 * 60);
1934        Console.WriteLine(t2.Result);
1935    }
1936}";
1937            var expected = @"
1938hello
193942
1940";
1941            CompileAndVerify(source, expectedOutput: expected);
1942        }
1943
1944        [Fact]
1945        public void AsyncInConditionalAccess()
1946        {
1947            var source = @"
1948using System;
1949using System.Collections.Generic;
1950using System.Threading.Tasks;
1951
1952class Test
1953{
1954
1955    class C1
1956    {
1957        public int M(int x)
1958        {
1959            return x;
1960        }
1961    }
1962
1963    public static int Get(int x)
1964    {
1965        Console.WriteLine(""> "" + x);
1966        return x;
1967    }
1968
1969    public static async Task<int> F(int x)
1970    {
1971        return await Task.Factory.StartNew(() => x);
1972    }
1973
1974    public static async Task<int?> G()
1975    {
1976        var c = new C1();
1977        return c?.M(await F(Get(42)));
1978    }
1979
1980    public static void Main()
1981    {
1982        var t = G();
1983        System.Console.WriteLine(t.Result);
1984    }
1985}";
1986            var expected = @"
1987> 42
198842";
1989            CompileAndVerifyExperimental(source, expected);
1990        }
1991
1992
1993        [Fact]
1994        public void Conformance_Awaiting_Methods_Generic01()
1995        {
1996            var source = @"
1997using System;
1998using System.Runtime.CompilerServices;
1999using System.Threading;
2000
2001//Implementation of you own async pattern
2002public class MyTask<T>
2003{
2004    public MyTaskAwaiter<T> GetAwaiter()
2005    {
2006        return new MyTaskAwaiter<T>();
2007    }
2008
2009    public async void Run<U>(U u) where U : MyTask<int>, new()
2010    {
2011        try
2012        {
2013            int tests = 0;
2014
2015            tests++;
2016            var rez = await u;
2017            if (rez == 0)
2018                Driver.Count++;
2019
2020            Driver.Result = Driver.Count - tests;
2021        }
2022        finally
2023        {
2024            //When test complete, set the flag.
2025            Driver.CompletedSignal.Set();
2026        }
2027    }
2028}
2029public class MyTaskAwaiter<T> : INotifyCompletion
2030{
2031    public void OnCompleted(Action continuationAction)
2032    {
2033    }
2034
2035    public T GetResult()
2036    {
2037        return default(T);
2038    }
2039
2040    public bool IsCompleted { get { return true; } }
2041}
2042//-------------------------------------
2043
2044class Driver
2045{
2046    public static int Result = -1;
2047    public static int Count = 0;
2048    public static AutoResetEvent CompletedSignal = new AutoResetEvent(false);
2049    static void Main()
2050    {
2051        new MyTask<int>().Run<MyTask<int>>(new MyTask<int>());
2052
2053        CompletedSignal.WaitOne();
2054
2055        // 0 - success
2056        // 1 - failed (test completed)
2057        // -1 - failed (test incomplete - deadlock, etc)
2058        Console.WriteLine(Driver.Result);
2059    }
2060}";
2061            CompileAndVerify(source, "0");
2062        }
2063
2064        [Fact]
2065        public void Conformance_Awaiting_Methods_Method01()
2066        {
2067            var source = @"
2068using System.Threading;
2069using System.Threading.Tasks;
2070using System;
2071
2072
2073public interface IExplicit
2074{
2075    Task Method(int x = 4);
2076}
2077
2078class C1 : IExplicit
2079{
2080    Task IExplicit.Method(int x)
2081    {
2082        //This will fail until Run and RunEx are merged back together
2083        return Task.Run(async () =>
2084        {
2085            await Task.Delay(1);
2086            Driver.Count++;
2087        });
2088    }
2089}
2090
2091class TestCase
2092{
2093    public async void Run()
2094    {
2095        try
2096        {
2097            int tests = 0;
2098            tests++;
2099
2100            C1 c = new C1();
2101            IExplicit e = (IExplicit)c;
2102            await e.Method();
2103
2104            Driver.Result = Driver.Count - tests;
2105        }
2106        finally
2107        {
2108            //When test complete, set the flag.
2109            Driver.CompletedSignal.Set();
2110        }
2111    }
2112}
2113
2114class Driver
2115{
2116    public static int Result = -1;
2117    public static int Count = 0;
2118    public static AutoResetEvent CompletedSignal = new AutoResetEvent(false);
2119    static void Main()
2120    {
2121        var t = new TestCase();
2122        t.Run();
2123
2124        CompletedSignal.WaitOne();
2125        // 0 - success
2126        // 1 - failed (test completed)
2127        // -1 - failed (test incomplete - deadlock, etc)
2128        Console.WriteLine(Driver.Result);
2129    }
2130}";
2131            CompileAndVerify(source, "0");
2132        }
2133
2134        [Fact]
2135        public void DoFinallyBodies()
2136        {
2137            var source = @"
2138using System.Threading.Tasks;
2139using System;
2140
2141class Driver
2142{
2143    public static int finally_count = 0;
2144
2145    static async Task F()
2146    {
2147        try
2148        {
2149            await Task.Factory.StartNew(() => { });
2150        }
2151        finally
2152        {
2153            Driver.finally_count++;
2154        }
2155    }
2156    
2157    static void Main()
2158    {
2159        var t = F();
2160        t.Wait();
2161        Console.WriteLine(Driver.finally_count);
2162    }
2163}";
2164            var expected = @"
21651
2166";
2167            CompileAndVerify(source, expected);
2168        }
2169
2170        [Fact]
2171        public void Conformance_Awaiting_Methods_Parameter003()
2172        {
2173            var source = @"
2174using System;
2175using System.Threading.Tasks;
2176using System.Collections.Generic;
2177using System.Threading;
2178
2179class TestCase
2180{
2181    public static int Count = 0;
2182    public static T Foo<T>(T t)
2183    {
2184        return t;
2185    }
2186
2187    public async static Task<T> Bar<T>(T t)
2188    {
2189        await Task.Delay(1);
2190        return t;
2191    }
2192
2193    public static async void Run()
2194    {
2195        try
2196   

Large files files are truncated, but you can click here to view the full file