Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
698b9e0e
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,发现更多精彩内容 >>
提交
698b9e0e
编写于
9月 20, 2017
作者:
V
Vladimir Sadov
提交者:
GitHub
9月 20, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #22203 from VSadov/relaxedEscape
Relaxed escape rules for spans
上级
a0912e3c
7b33a48a
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
579 addition
and
369 deletion
+579
-369
src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs
src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs
+89
-69
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
+5
-5
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ConditionalOperator.cs
...wering/LocalRewriter/LocalRewriter_ConditionalOperator.cs
+12
-2
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs
...p/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs
+81
-18
src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs
...pilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs
+392
-275
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs
浏览文件 @
698b9e0e
此差异已折叠。
点击以展开。
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
浏览文件 @
698b9e0e
...
@@ -3629,20 +3629,20 @@ private BoundExpression BindConditionalOperator(ConditionalExpressionSyntax node
...
@@ -3629,20 +3629,20 @@ private BoundExpression BindConditionalOperator(ConditionalExpressionSyntax node
{
{
var
currentScope
=
this
.
LocalScopeDepth
;
var
currentScope
=
this
.
LocalScopeDepth
;
//
ref
-escape must agree on both branches.
//
val
-escape must agree on both branches.
uint
whenTrueEscape
=
Get
Ref
Escape
(
trueExpr
,
currentScope
);
uint
whenTrueEscape
=
Get
Val
Escape
(
trueExpr
,
currentScope
);
uint
whenFalseEscape
=
Get
Ref
Escape
(
falseExpr
,
currentScope
);
uint
whenFalseEscape
=
Get
Val
Escape
(
falseExpr
,
currentScope
);
if
(
whenTrueEscape
!=
whenFalseEscape
)
if
(
whenTrueEscape
!=
whenFalseEscape
)
{
{
// ask the one with narrower escape, for the wider - hopefully the errors will make the violation easier to fix.
// ask the one with narrower escape, for the wider - hopefully the errors will make the violation easier to fix.
if
(
whenTrueEscape
<
whenFalseEscape
)
if
(
whenTrueEscape
<
whenFalseEscape
)
{
{
Check
Ref
Escape
(
falseExpr
.
Syntax
,
falseExpr
,
currentScope
,
whenTrueEscape
,
checkingReceiver
:
false
,
diagnostics
:
diagnostics
);
Check
Val
Escape
(
falseExpr
.
Syntax
,
falseExpr
,
currentScope
,
whenTrueEscape
,
checkingReceiver
:
false
,
diagnostics
:
diagnostics
);
}
}
else
else
{
{
Check
Ref
Escape
(
trueExpr
.
Syntax
,
trueExpr
,
currentScope
,
whenFalseEscape
,
checkingReceiver
:
false
,
diagnostics
:
diagnostics
);
Check
Val
Escape
(
trueExpr
.
Syntax
,
trueExpr
,
currentScope
,
whenFalseEscape
,
checkingReceiver
:
false
,
diagnostics
:
diagnostics
);
}
}
diagnostics
.
Add
(
ErrorCode
.
ERR_MismatchedRefEscapeInTernary
,
node
.
Location
);
diagnostics
.
Add
(
ErrorCode
.
ERR_MismatchedRefEscapeInTernary
,
node
.
Location
);
...
...
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ConditionalOperator.cs
浏览文件 @
698b9e0e
...
@@ -49,11 +49,21 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node
...
@@ -49,11 +49,21 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node
ConstantValue
conditionConstantValue
=
rewrittenCondition
.
ConstantValue
;
ConstantValue
conditionConstantValue
=
rewrittenCondition
.
ConstantValue
;
if
(
conditionConstantValue
==
ConstantValue
.
True
)
if
(
conditionConstantValue
==
ConstantValue
.
True
)
{
{
return
EnsureNotAssignableIfUsedAsMethodReceiver
(
rewrittenConsequence
);
if
(!
isRef
)
{
rewrittenConsequence
=
EnsureNotAssignableIfUsedAsMethodReceiver
(
rewrittenConsequence
);
}
return
rewrittenConsequence
;
}
}
else
if
(
conditionConstantValue
==
ConstantValue
.
False
)
else
if
(
conditionConstantValue
==
ConstantValue
.
False
)
{
{
return
EnsureNotAssignableIfUsedAsMethodReceiver
(
rewrittenAlternative
);
if
(!
isRef
)
{
rewrittenAlternative
=
EnsureNotAssignableIfUsedAsMethodReceiver
(
rewrittenAlternative
);
}
return
rewrittenAlternative
;
}
}
else
else
{
{
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs
浏览文件 @
698b9e0e
...
@@ -662,10 +662,7 @@ static void Main()
...
@@ -662,10 +662,7 @@ static void Main()
comp
.
VerifyEmitDiagnostics
(
comp
.
VerifyEmitDiagnostics
(
// (15,27): error CS8168: Cannot return local 'local1' by reference because it is not a ref local
// (15,27): error CS8168: Cannot return local 'local1' by reference because it is not a ref local
// return ref b? ref local1: ref local2;
// return ref b? ref local1: ref local2;
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local1"
).
WithArguments
(
"local1"
).
WithLocation
(
15
,
27
),
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local1"
).
WithArguments
(
"local1"
).
WithLocation
(
15
,
27
)
// (15,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref b? ref local1: ref local2;
Diagnostic
(
ErrorCode
.
ERR_RefReturnLvalueExpected
,
"b? ref local1: ref local2"
).
WithLocation
(
15
,
20
)
);
);
}
}
...
@@ -696,10 +693,7 @@ static void Main()
...
@@ -696,10 +693,7 @@ static void Main()
comp
.
VerifyEmitDiagnostics
(
comp
.
VerifyEmitDiagnostics
(
// (14,37): error CS8168: Cannot return local 'local2' by reference because it is not a ref local
// (14,37): error CS8168: Cannot return local 'local2' by reference because it is not a ref local
// return ref b? ref val1: ref local2;
// return ref b? ref val1: ref local2;
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local2"
).
WithArguments
(
"local2"
).
WithLocation
(
14
,
37
),
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local2"
).
WithArguments
(
"local2"
).
WithLocation
(
14
,
37
)
// (14,20): error CS8351: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes.
// return ref b? ref val1: ref local2;
Diagnostic
(
ErrorCode
.
ERR_MismatchedRefEscapeInTernary
,
"b? ref val1: ref local2"
).
WithLocation
(
14
,
20
)
);
);
}
}
...
@@ -735,10 +729,7 @@ struct S1
...
@@ -735,10 +729,7 @@ struct S1
comp
.
VerifyEmitDiagnostics
(
comp
.
VerifyEmitDiagnostics
(
// (14,38): error CS8168: Cannot return local 'local2' by reference because it is not a ref local
// (14,38): error CS8168: Cannot return local 'local2' by reference because it is not a ref local
// return ref (b? ref val1: ref local2).x;
// return ref (b? ref val1: ref local2).x;
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local2"
).
WithArguments
(
"local2"
).
WithLocation
(
14
,
38
),
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local2"
).
WithArguments
(
"local2"
).
WithLocation
(
14
,
38
)
// (14,21): error CS8351: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes.
// return ref (b? ref val1: ref local2).x;
Diagnostic
(
ErrorCode
.
ERR_MismatchedRefEscapeInTernary
,
"b? ref val1: ref local2"
).
WithLocation
(
14
,
21
)
);
);
}
}
...
@@ -773,12 +764,9 @@ struct S1
...
@@ -773,12 +764,9 @@ struct S1
var
comp
=
CreateCompilationWithMscorlib45
(
source
,
options
:
TestOptions
.
ReleaseExe
);
var
comp
=
CreateCompilationWithMscorlib45
(
source
,
options
:
TestOptions
.
ReleaseExe
);
comp
.
VerifyEmitDiagnostics
(
comp
.
VerifyEmitDiagnostics
(
// (14,46): error CS8168: Cannot return local 'local2' by reference because it is not a ref local
// (15,20): error CS8157: Cannot return 'temp' by reference because it was initialized to a value that cannot be returned by reference
// ref var temp = ref (b? ref val1: ref local2).x;
// return ref temp;
Diagnostic
(
ErrorCode
.
ERR_RefReturnLocal
,
"local2"
).
WithArguments
(
"local2"
).
WithLocation
(
14
,
46
),
Diagnostic
(
ErrorCode
.
ERR_RefReturnNonreturnableLocal
,
"temp"
).
WithArguments
(
"temp"
).
WithLocation
(
15
,
20
)
// (14,29): error CS8351: Branches of a ref ternary operator cannot refer to variables with incompatible declaration scopes.
// ref var temp = ref (b? ref val1: ref local2).x;
Diagnostic
(
ErrorCode
.
ERR_MismatchedRefEscapeInTernary
,
"b? ref val1: ref local2"
).
WithLocation
(
14
,
29
)
);
);
}
}
...
@@ -828,6 +816,81 @@ .maxstack 1
...
@@ -828,6 +816,81 @@ .maxstack 1
"
);
"
);
}
}
[
Fact
]
public
void
TestRefConditionalSafeToReturn2
()
{
var
source
=
@"
class C
{
static void Main()
{
Test() ++;
System.Console.WriteLine(val1.x);
}
static ref int Test()
{
return ref (true? ref val1: ref val2).x;
}
static S1 val1;
static S1 val2;
struct S1
{
public int x;
}
}
"
;
var
comp
=
CompileAndVerify
(
source
,
expectedOutput
:
"1"
,
verify
:
false
);
comp
.
VerifyDiagnostics
();
comp
.
VerifyIL
(
"C.Test"
,
@"
{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldsflda ""C.S1 C.val1""
IL_0005: ldflda ""int C.S1.x""
IL_000a: ret
}
"
);
}
[
Fact
]
public
void
TestRefConditionalSafeToReturn3
()
{
var
source
=
@"
class C
{
static void Main()
{
(false? ref val1: ref val2) = (true? 1: val2);
(true? ref val1: ref val2) = (false? ref val1: ref val2);
System.Console.WriteLine(val1);
}
static int val1;
static int val2;
}
"
;
var
comp
=
CompileAndVerify
(
source
,
expectedOutput
:
"1"
,
verify
:
false
);
comp
.
VerifyDiagnostics
();
comp
.
VerifyIL
(
"C.Main()"
,
@"
{
// Code size 27 (0x1b)
.maxstack 1
IL_0000: ldc.i4.1
IL_0001: stsfld ""int C.val2""
IL_0006: ldsfld ""int C.val2""
IL_000b: stsfld ""int C.val1""
IL_0010: ldsfld ""int C.val1""
IL_0015: call ""void System.Console.WriteLine(int)""
IL_001a: ret
}
"
);
}
[
Fact
]
[
Fact
]
public
void
TestRefConditionalDifferentTypes1
()
public
void
TestRefConditionalDifferentTypes1
()
{
{
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs
浏览文件 @
698b9e0e
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录