diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 38cefd87ac91f7cbe9185176742ad11c60040b40..0aa8748f43f8b365c5a7a4f806a0ca0bf0abfd90 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -3371,11 +3371,20 @@ private ImmutableArray BindCatchBlocks(SyntaxList.GetInstance(n); + var hasCatchAll = false; + foreach (var catchSyntax in catchClauses) { + if (hasCatchAll) + { + diagnostics.Add(ErrorCode.ERR_TooManyCatches, catchSyntax.CatchKeyword.GetLocation()); + } + var catchBinder = this.GetBinder(catchSyntax); var catchBlock = catchBinder.BindCatchBlock(catchSyntax, catchBlocks, diagnostics); catchBlocks.Add(catchBlock); + + hasCatchAll |= catchSyntax.Declaration == null && catchSyntax.Filter == null; } return catchBlocks.ToImmutableAndFree(); } diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 3cab42a01ca2c12f6a19024ee6a6fdaa381575ec..012d1a0ec4685e6ec1c4da0f1ffaaf5d35135bb7 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -7649,7 +7649,6 @@ private TryStatementSyntax ParseTryStatement() try { bool hasEnd = false; - bool hasCatchAll = false; if (this.CurrentToken.Kind == SyntaxKind.CatchKeyword) { @@ -7657,9 +7656,7 @@ private TryStatementSyntax ParseTryStatement() catches = _pool.Allocate(); while (this.CurrentToken.Kind == SyntaxKind.CatchKeyword) { - var clause = this.ParseCatchClause(hasCatchAll); - hasCatchAll |= clause.Declaration == null && clause.Filter == null; - catches.Add(clause); + catches.Add(this.ParseCatchClause()); } } @@ -7704,18 +7701,12 @@ private bool IsEndOfTryBlock() || this.CurrentToken.Kind == SyntaxKind.FinallyKeyword; } - private CatchClauseSyntax ParseCatchClause(bool hasCatchAll) + private CatchClauseSyntax ParseCatchClause() { Debug.Assert(this.CurrentToken.Kind == SyntaxKind.CatchKeyword); var @catch = this.EatToken(); - // Check for the error of catch clause following empty catch here. - if (hasCatchAll) - { - @catch = this.AddError(@catch, ErrorCode.ERR_TooManyCatches); - } - CatchDeclarationSyntax decl = null; var saveTerm = _termState; diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index 5366a4b8b418b242e25d5f3db979fe73dad72ad1..863d2fbc6d21a8cb4e030d71788201df4adb1127 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -1711,10 +1711,19 @@ public static int Main() } "; - ParseAndValidate(test, - Diagnostic(ErrorCode.ERR_TooManyCatches, "catch"), - Diagnostic(ErrorCode.ERR_TooManyCatches, "catch"), - Diagnostic(ErrorCode.ERR_TooManyCatches, "catch")); + CreateCompilationWithMscorlib(test).VerifyDiagnostics( + // (16,9): error CS1017: Catch clauses cannot follow the general catch clause of a try statement + // catch (S1) {} + Diagnostic(ErrorCode.ERR_TooManyCatches, "catch").WithLocation(16, 9), + // (17,9): error CS1017: Catch clauses cannot follow the general catch clause of a try statement + // catch (S) {} + Diagnostic(ErrorCode.ERR_TooManyCatches, "catch").WithLocation(17, 9), + // (18,9): error CS1017: Catch clauses cannot follow the general catch clause of a try statement + // catch when (false) {} + Diagnostic(ErrorCode.ERR_TooManyCatches, "catch").WithLocation(18, 9), + // (18,21): warning CS7095: Filter expression is a constant, consider removing the filter + // catch when (false) {} + Diagnostic(ErrorCode.WRN_FilterIsConstant, "false").WithLocation(18, 21)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs index 745f146f4cfb3c07ceb0957230c2645daf8cddc0..df44075b3a13ac6b31e8366b66d50c90da999371 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs @@ -3979,10 +3979,9 @@ public void TestCatchAfterCatchStart() Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); - Assert.Equal(3, file.Errors().Length); + Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); - Assert.Equal((int)ErrorCode.ERR_TooManyCatches, file.Errors()[2].Code); } [Fact]