提交 bae7d81c 编写于 作者: N Neal Gafter

Do not allow await in catch/finally un language version 5

Fixes #2725
上级 1310d8bc
......@@ -118,32 +118,42 @@ private bool ReportBadAwaitWithoutAsync(CSharpSyntaxNode node, DiagnosticBag dia
}
/// <summary>
/// Report diagnostics if the await expression occurs in an unsafe context.
/// Errors for await in lock statement, finally block, or catch clause are detected
/// and reported in the warnings pass.
/// Report diagnostics if the await expression occurs in a context where it is not allowed.
/// </summary>
/// <returns>True if errors were found.</returns>
private bool ReportBadAwaitContext(CSharpSyntaxNode node, DiagnosticBag diagnostics)
{
bool hasErrors = false;
if (this.InUnsafeRegion && !this.Flags.Includes(BinderFlags.AllowAwaitInUnsafeContext))
{
Error(diagnostics, ErrorCode.ERR_AwaitInUnsafeContext, node);
hasErrors = true;
return true;
}
else if (this.Flags.Includes(BinderFlags.InLockBody))
{
Error(diagnostics, ErrorCode.ERR_BadAwaitInLock, node);
hasErrors = true;
return true;
}
else if (this.Flags.Includes(BinderFlags.InCatchFilter))
{
Error(diagnostics, ErrorCode.ERR_BadAwaitInCatchFilter, node);
hasErrors = true;
return true;
}
else if (this.Flags.Includes(BinderFlags.InFinallyBlock) &&
(node.SyntaxTree as CSharpSyntaxTree)?.Options?.IsFeatureEnabled(MessageID.IDS_AwaitInCatchAndFinally) == false)
{
Error(diagnostics, ErrorCode.ERR_BadAwaitInFinally, node);
return true;
}
else if (this.Flags.Includes(BinderFlags.InCatchBlock) &&
(node.SyntaxTree as CSharpSyntaxTree)?.Options?.IsFeatureEnabled(MessageID.IDS_AwaitInCatchAndFinally) == false)
{
Error(diagnostics, ErrorCode.ERR_BadAwaitInCatch, node);
return true;
}
else
{
return false;
}
return hasErrors;
}
/// <summary>
......
......@@ -196,6 +196,13 @@ public new CSharpParseOptions WithFeatures(IEnumerable<KeyValuePair<string, stri
}
}
internal bool IsFeatureEnabled(MessageID feature)
{
LanguageVersion availableVersion = LanguageVersion;
LanguageVersion requiredVersion = feature.RequiredVersion();
return availableVersion >= requiredVersion;
}
public override bool Equals(object obj)
{
return this.Equals(obj as CSharpParseOptions);
......
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.0
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
......@@ -8692,6 +8692,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to await in catch blocks and finally blocks.
/// </summary>
internal static string IDS_AwaitInCatchAndFinally {
get {
return ResourceManager.GetString("IDS_AwaitInCatchAndFinally", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to collection.
/// </summary>
......
......@@ -4594,6 +4594,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="IDS_FeatureInterpolatedStrings" xml:space="preserve">
<value>interpolated strings</value>
</data>
<data name="IDS_AwaitInCatchAndFinally" xml:space="preserve">
<value>await in catch blocks and finally blocks</value>
</data>
<data name="ERR_UnescapedCurly" xml:space="preserve">
<value>A '{0}' character must be escaped (by doubling) in an interpolated string.</value>
</data>
......
......@@ -110,6 +110,7 @@ internal enum MessageID
IDS_FeatureUsingStatic = MessageBase + 12701,
IDS_FeatureInterpolatedStrings = MessageBase + 12702,
IDS_OperationCausedStackOverflow = MessageBase + 12703,
IDS_AwaitInCatchAndFinally = MessageBase + 12704,
}
......@@ -161,6 +162,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
case MessageID.IDS_FeatureDictionaryInitializer:
case MessageID.IDS_FeatureUsingStatic:
case MessageID.IDS_FeatureInterpolatedStrings:
case MessageID.IDS_AwaitInCatchAndFinally:
return LanguageVersion.CSharp6;
// C# 5 features.
......
......@@ -1056,9 +1056,7 @@ protected TNode CheckFeatureAvailability<TNode>(TNode node, MessageID feature, b
protected bool IsFeatureEnabled(MessageID feature)
{
LanguageVersion availableVersion = this.Options.LanguageVersion;
LanguageVersion requiredVersion = feature.RequiredVersion();
return availableVersion >= requiredVersion;
return this.Options.IsFeatureEnabled(feature);
}
}
}
......@@ -890,7 +890,15 @@ class Test
}
}
}";
CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp5)).VerifyDiagnostics(
// (20,17): error CS1984: Cannot await in the body of a finally clause
// await Task.Factory.StartNew(() => { });
Diagnostic(ErrorCode.ERR_BadAwaitInFinally, "await Task.Factory.StartNew(() => { })").WithLocation(20, 17),
// (30,17): error CS1984: Cannot await in the body of a finally clause
// await Task.Factory.StartNew(() => { });
Diagnostic(ErrorCode.ERR_BadAwaitInFinally, "await Task.Factory.StartNew(() => { })").WithLocation(30, 17)
);
CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6)).VerifyDiagnostics();
}
[Fact]
......@@ -914,7 +922,12 @@ class Test
}
}
}";
CreateCompilationWithMscorlib45(source).VerifyDiagnostics();
CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp5)).VerifyDiagnostics(
// (12,13): error CS1985: Cannot await in a catch clause
// await Task.Factory.StartNew(() => { });
Diagnostic(ErrorCode.ERR_BadAwaitInCatch, "await Task.Factory.StartNew(() => { })").WithLocation(12, 13)
);
CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6)).VerifyDiagnostics();
}
[Fact]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册