Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
f7ca4ebf
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
f7ca4ebf
编写于
5月 14, 2020
作者:
R
Rikki Gibson
提交者:
GitHub
5月 14, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Diagnose bad 'ref' locals in switch sections (#44194)
上级
b61d9d28
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
159 addition
and
24 deletion
+159
-24
src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
+18
-11
src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
+2
-8
src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs
...Sharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs
+139
-5
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
浏览文件 @
f7ca4ebf
...
...
@@ -969,10 +969,9 @@ protected BoundExpression BindInferredVariableInitializer(DiagnosticBag diagnost
bool
nameConflict
=
localSymbol
.
ScopeBinder
.
ValidateDeclarationNameConflictsInScope
(
localSymbol
,
diagnostics
);
bool
hasErrors
=
false
;
var
containingMethod
=
this
.
ContainingMemberOrLambda
as
MethodSymbol
;
if
(
containingMethod
!=
null
&&
containingMethod
.
IsAsync
&&
localSymbol
.
RefKind
!=
RefKind
.
None
)
if
(
localSymbol
.
RefKind
!=
RefKind
.
None
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_BadAsyncLocalType
,
declarator
);
CheckRefLocalInAsyncOrIteratorMethod
(
localSymbol
.
IdentifierToken
,
diagnostics
);
}
EqualsValueClauseSyntax
equalsClauseSyntax
=
declarator
.
Initializer
;
...
...
@@ -1150,6 +1149,22 @@ protected BoundExpression BindInferredVariableInitializer(DiagnosticBag diagnost
hasErrors
:
hasErrors
|
nameConflict
);
}
protected
bool
CheckRefLocalInAsyncOrIteratorMethod
(
SyntaxToken
identifierToken
,
DiagnosticBag
diagnostics
)
{
if
(
IsInAsyncMethod
())
{
Error
(
diagnostics
,
ErrorCode
.
ERR_BadAsyncLocalType
,
identifierToken
);
return
true
;
}
else
if
(
IsDirectlyInIterator
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_BadIteratorLocalType
,
identifierToken
);
return
true
;
}
return
false
;
}
internal
ImmutableArray
<
BoundExpression
>
BindDeclaratorArguments
(
VariableDeclaratorSyntax
declarator
,
DiagnosticBag
diagnostics
)
{
// It is possible that we have a bracketed argument list, like "int x[];" or "int x[123];"
...
...
@@ -1732,14 +1747,6 @@ private BoundBlock BindBlockParts(BlockSyntax node, DiagnosticBag diagnostics)
{
Debug
.
Assert
(!
diagnostics
.
IsEmptyWithoutResolution
);
}
foreach
(
var
local
in
locals
)
{
if
(
local
.
RefKind
!=
RefKind
.
None
)
{
diagnostics
.
Add
(
ErrorCode
.
ERR_BadIteratorLocalType
,
local
.
Locations
[
0
]);
}
}
}
return
new
BoundBlock
(
...
...
src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
浏览文件 @
f7ca4ebf
...
...
@@ -269,18 +269,12 @@ private BoundForEachStatement BindForEachPartsWorker(DiagnosticBag diagnostics,
if
(
local
.
RefKind
!=
RefKind
.
None
)
{
// The ref-escape of a ref-returning property is decided
// by the value escape of its receiver
m
, in this case the
// by the value escape of its receiver, in this case the
// collection
local
.
SetRefEscape
(
collectionEscape
);
if
(
IsDirectlyInIterator
)
if
(
CheckRefLocalInAsyncOrIteratorMethod
(
local
.
IdentifierToken
,
diagnostics
)
)
{
diagnostics
.
Add
(
ErrorCode
.
ERR_BadIteratorLocalType
,
local
.
IdentifierToken
.
GetLocation
());
hasErrors
=
true
;
}
else
if
(
IsInAsyncMethod
())
{
diagnostics
.
Add
(
ErrorCode
.
ERR_BadAsyncLocalType
,
local
.
IdentifierToken
.
GetLocation
());
hasErrors
=
true
;
}
}
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs
浏览文件 @
f7ca4ebf
...
...
@@ -1174,7 +1174,7 @@ async Task M()
comp
.
VerifyDiagnostics
(
// (7,26): error CS8177: Async methods cannot have by-reference locals
// ref readonly int x = ref (new int[1])[0];
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"x
= ref (new int[1])[0]
"
).
WithLocation
(
7
,
26
));
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"x"
).
WithLocation
(
7
,
26
));
}
[
Fact
]
...
...
@@ -1197,6 +1197,140 @@ IEnumerable<int> M()
Diagnostic
(
ErrorCode
.
ERR_BadIteratorLocalType
,
"x"
).
WithLocation
(
7
,
26
));
}
[
Fact
]
public
void
RefReadonlyInSwitchCaseInIterator_01
()
{
var
comp
=
CreateCompilation
(
@"
using System.Collections.Generic;
class C
{
IEnumerable<int> M()
{
switch (this)
{
default:
ref readonly int x = ref (new int[1])[0]; // 1
yield return 1;
yield return x;
local();
void local()
{
ref readonly int z = ref (new int[1])[0];
}
break;
}
}
}"
);
comp
.
VerifyDiagnostics
(
// (10,34): error CS8176: Iterators cannot have by-reference locals
// ref readonly int x = ref (new int[1])[0]; // 1
Diagnostic
(
ErrorCode
.
ERR_BadIteratorLocalType
,
"x"
).
WithLocation
(
10
,
34
));
}
[
Fact
]
public
void
RefReadonlyInSwitchCaseInIterator_02
()
{
var
comp
=
CreateCompilation
(
@"
using System.Collections.Generic;
class C
{
IEnumerable<int> M()
{
switch (this)
{
default:
ref readonly int x; // 1, 2
yield return 1;
yield return x; // 3
break;
}
}
}"
);
comp
.
VerifyDiagnostics
(
// (10,34): error CS8176: Iterators cannot have by-reference locals
// ref readonly int x; // 1, 2
Diagnostic
(
ErrorCode
.
ERR_BadIteratorLocalType
,
"x"
).
WithLocation
(
10
,
34
),
// (10,34): error CS8174: A declaration of a by-reference variable must have an initializer
// ref readonly int x; // 1, 2
Diagnostic
(
ErrorCode
.
ERR_ByReferenceVariableMustBeInitialized
,
"x"
).
WithLocation
(
10
,
34
),
// (12,30): error CS0165: Use of unassigned local variable 'x'
// yield return x; // 3
Diagnostic
(
ErrorCode
.
ERR_UseDefViolation
,
"x"
).
WithArguments
(
"x"
).
WithLocation
(
12
,
30
));
}
[
Fact
]
public
void
RefReadonlyInSwitchCaseInIterator_03
()
{
var
comp
=
CreateCompilation
(
@"
using System.Collections.Generic;
class C
{
IEnumerable<int> M()
{
switch (this)
{
default:
foreach (ref readonly int x in (new int[1]))
yield return 1;
break;
}
}
}"
);
comp
.
VerifyDiagnostics
(
// (10,43): error CS8176: Iterators cannot have by-reference locals
// foreach (ref readonly int x in (new int[1]))
Diagnostic
(
ErrorCode
.
ERR_BadIteratorLocalType
,
"x"
).
WithLocation
(
10
,
43
));
}
[
Fact
]
public
void
RefReadonlyInEmbeddedStatementInIterator
()
{
var
comp
=
CreateCompilation
(
@"
using System.Collections.Generic;
class C
{
IEnumerable<int> M()
{
if (true)
ref int x = ref (new int[1])[0]; // 1, 2
yield return 1;
}
}"
);
comp
.
VerifyDiagnostics
(
// (8,13): error CS1023: Embedded statement cannot be a declaration or labeled statement
// ref int x = ref (new int[1])[0]; // 1, 2
Diagnostic
(
ErrorCode
.
ERR_BadEmbeddedStmt
,
"ref int x = ref (new int[1])[0];"
).
WithLocation
(
8
,
13
),
// (8,21): error CS8176: Iterators cannot have by-reference locals
// ref int x = ref (new int[1])[0]; // 1, 2
Diagnostic
(
ErrorCode
.
ERR_BadIteratorLocalType
,
"x"
).
WithLocation
(
8
,
21
));
}
[
Fact
]
public
void
RefReadonlyInEmbeddedStatementInAsync
()
{
var
comp
=
CreateCompilation
(
@"
using System.Threading.Tasks;
class C
{
async Task M()
{
if (true)
ref int x = ref (new int[1])[0]; // 1, 2
await Task.Yield();
}
}"
);
comp
.
VerifyDiagnostics
(
// (8,13): error CS1023: Embedded statement cannot be a declaration or labeled statement
// ref int x = ref (new int[1])[0]; // 1, 2
Diagnostic
(
ErrorCode
.
ERR_BadEmbeddedStmt
,
"ref int x = ref (new int[1])[0];"
).
WithLocation
(
8
,
13
),
// (8,21): error CS8177: Async methods cannot have by-reference locals
// ref int x = ref (new int[1])[0]; // 1, 2
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"x"
).
WithLocation
(
8
,
21
));
}
[
Fact
]
public
void
RefReadonlyLocalNotWritable
()
{
...
...
@@ -2711,10 +2845,10 @@ async Task TestMethod()
CreateCompilationWithMscorlib45
(
code
).
VerifyDiagnostics
(
// (8,17): error CS8177: Async methods cannot have by-reference locals
// ref int y = ref x;
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"y
= ref x
"
).
WithLocation
(
8
,
17
),
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"y"
).
WithLocation
(
8
,
17
),
// (11,21): error CS8177: Async methods cannot have by-reference locals
// ref int z = ref x;
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"z
= ref x
"
).
WithLocation
(
11
,
21
));
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"z"
).
WithLocation
(
11
,
21
));
}
[
Fact
,
WorkItem
(
13073
,
"https://github.com/dotnet/roslyn/issues/13073"
)]
...
...
@@ -3029,9 +3163,9 @@ static async void Goo()
"
;
CreateCompilationWithMscorlib46
(
text
).
VerifyDiagnostics
(
// (8,17): error CS8
932
: Async methods cannot have by-reference locals
// (8,17): error CS8
177
: Async methods cannot have by-reference locals
// ref int i = ref field;
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"i
= ref field
"
).
WithLocation
(
8
,
17
),
Diagnostic
(
ErrorCode
.
ERR_BadAsyncLocalType
,
"i"
).
WithLocation
(
8
,
17
),
// (6,23): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
// static async void Goo()
Diagnostic
(
ErrorCode
.
WRN_AsyncLacksAwaits
,
"Goo"
).
WithLocation
(
6
,
23
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录