Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
179d459e
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,发现更多精彩内容 >>
未验证
提交
179d459e
编写于
7月 23, 2018
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Addressed more PR feedback.
上级
631e421a
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
92 addition
and
26 deletion
+92
-26
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
+7
-3
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
...rp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
+85
-23
未找到文件。
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
浏览文件 @
179d459e
...
@@ -1462,10 +1462,12 @@ protected override void AfterLeftChildHasBeenVisited(BoundBinaryOperator binary)
...
@@ -1462,10 +1462,12 @@ protected override void AfterLeftChildHasBeenVisited(BoundBinaryOperator binary)
if
(
operandComparedToNull
.
Type
?.
IsReferenceType
==
true
)
if
(
operandComparedToNull
.
Type
?.
IsReferenceType
==
true
)
{
{
var
slotBuilder
=
ArrayBuilder
<
int
>.
GetInstance
();
var
slotBuilder
=
ArrayBuilder
<
int
>.
GetInstance
();
// Set all nested conditional slots. For example in a?.b?.c we'll set a, b, and c
getOperandSlots
(
operandComparedToNull
,
slotBuilder
);
getOperandSlots
(
operandComparedToNull
,
slotBuilder
);
Normalize
(
ref
this
.
State
);
if
(
slotBuilder
.
Count
!=
0
)
if
(
slotBuilder
.
Count
!=
0
)
{
{
Normalize
(
ref
this
.
State
);
Split
();
Split
();
ref
LocalState
state
=
ref
(
op
==
BinaryOperatorKind
.
Equal
)
?
ref
this
.
StateWhenFalse
:
ref
this
.
StateWhenTrue
;
ref
LocalState
state
=
ref
(
op
==
BinaryOperatorKind
.
Equal
)
?
ref
this
.
StateWhenFalse
:
ref
this
.
StateWhenTrue
;
foreach
(
int
slot
in
slotBuilder
)
foreach
(
int
slot
in
slotBuilder
)
...
@@ -1536,13 +1538,15 @@ void getOperandSlots(BoundExpression operand, ArrayBuilder<int> slotBuilder)
...
@@ -1536,13 +1538,15 @@ void getOperandSlots(BoundExpression operand, ArrayBuilder<int> slotBuilder)
// c.D has been invoked, c must be nonnull or we've thrown a NullRef), revisit whether
// c.D has been invoked, c must be nonnull or we've thrown a NullRef), revisit whether
// we need more special handling here
// we need more special handling here
// If we're in this case, then all previous BoundCondtionalReceivers must have been handled.
Debug
.
Assert
(
_lastConditionalAccessSlot
==
-
1
);
slot
=
MakeSlot
(
operand
);
slot
=
MakeSlot
(
operand
);
if
(
slot
>
0
)
if
(
slot
>
0
)
{
{
// If we got a slot then all previous BoundCondtionalReceivers must have been handled.
Debug
.
Assert
(
_lastConditionalAccessSlot
==
-
1
);
slotBuilder
.
Add
(
slot
);
slotBuilder
.
Add
(
slot
);
}
}
break
;
break
;
}
}
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
浏览文件 @
179d459e
...
@@ -11756,7 +11756,7 @@ void Test1(C? c1)
...
@@ -11756,7 +11756,7 @@ void Test1(C? c1)
}
}
else
else
{
{
c1._cField.ToString(); // warn
c1._cField.ToString(); // warn
1 2
}
}
}
}
...
@@ -11769,7 +11769,7 @@ void Test2()
...
@@ -11769,7 +11769,7 @@ void Test2()
}
}
else
else
{
{
c2._cField.ToString(); // warn
x2
c2._cField.ToString(); // warn
3 4
}
}
}
}
...
@@ -11782,11 +11782,11 @@ void Test3(C? c3)
...
@@ -11782,11 +11782,11 @@ void Test3(C? c3)
else if (c3?._cField != null)
else if (c3?._cField != null)
{
{
c3._cField.ToString();
c3._cField.ToString();
c3._cField._cField.ToString(); // warn
c3._cField._cField.ToString(); // warn
5
}
}
else
else
{
{
c3.ToString(); // warn
c3.ToString(); // warn
6
}
}
}
}
...
@@ -11798,7 +11798,7 @@ void Test4(C? c4)
...
@@ -11798,7 +11798,7 @@ void Test4(C? c4)
}
}
else
else
{
{
c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
x3
c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
7 8 9
}
}
}
}
...
@@ -11806,7 +11806,7 @@ void Test5(C? c5)
...
@@ -11806,7 +11806,7 @@ void Test5(C? c5)
{
{
if (c5?._cField == null)
if (c5?._cField == null)
{
{
c5._cField.ToString(); // warn
x2
c5._cField.ToString(); // warn
10 11
}
}
else
else
{
{
...
@@ -11818,7 +11818,7 @@ void Test6(C? c6)
...
@@ -11818,7 +11818,7 @@ void Test6(C? c6)
{
{
if (c6?._cField?.GetC() != null)
if (c6?._cField?.GetC() != null)
{
{
c6._cField.GetC().ToString(); // warn
c6._cField.GetC().ToString(); // warn
12
}
}
}
}
...
@@ -11834,45 +11834,46 @@ void Test7(C? c7)
...
@@ -11834,45 +11834,46 @@ void Test7(C? c7)
compilation.VerifyDiagnostics(
compilation.VerifyDiagnostics(
// (17,13): warning CS8602: Possible dereference of a null reference.
// (17,13): warning CS8602: Possible dereference of a null reference.
// c1._cField.ToString(); // warn
// c1._cField.ToString(); // warn
1 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1").WithLocation(17, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1").WithLocation(17, 13),
// (17,13): warning CS8602: Possible dereference of a null reference.
// (17,13): warning CS8602: Possible dereference of a null reference.
// c1._cField.ToString(); // warn
// c1._cField.ToString(); // warn
1 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1._cField").WithLocation(17, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1._cField").WithLocation(17, 13),
// (30,13): warning CS8602: Possible dereference of a null reference.
// (30,13): warning CS8602: Possible dereference of a null reference.
// c2._cField.ToString(); // warn
x2
// c2._cField.ToString(); // warn
3 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c2").WithLocation(30, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c2").WithLocation(30, 13),
// (30,13): warning CS8602: Possible dereference of a null reference.
// (30,13): warning CS8602: Possible dereference of a null reference.
// c2._cField.ToString(); // warn
x2
// c2._cField.ToString(); // warn
3 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c2._cField").WithLocation(30, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c2._cField").WithLocation(30, 13),
// (43,13): warning CS8602: Possible dereference of a null reference.
// (43,13): warning CS8602: Possible dereference of a null reference.
// c3._cField._cField.ToString(); // warn
// c3._cField._cField.ToString(); // warn
5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c3._cField._cField").WithLocation(43, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c3._cField._cField").WithLocation(43, 13),
// (47,13): warning CS8602: Possible dereference of a null reference.
// (47,13): warning CS8602: Possible dereference of a null reference.
// c3.ToString(); // warn
// c3.ToString(); // warn
6
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c3").WithLocation(47, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c3").WithLocation(47, 13),
// (59,13): warning CS8602: Possible dereference of a null reference.
// (59,13): warning CS8602: Possible dereference of a null reference.
// c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
x3
// c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
7 8 9
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c4").WithLocation(59, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c4").WithLocation(59, 13),
// (59,13): warning CS8602: Possible dereference of a null reference.
// (59,13): warning CS8602: Possible dereference of a null reference.
// c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
x3
// c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
7 8 9
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c4._nonNullCField._cField").WithLocation(59, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c4._nonNullCField._cField").WithLocation(59, 13),
// (59,13): warning CS8602: Possible dereference of a null reference.
// (59,13): warning CS8602: Possible dereference of a null reference.
// c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
x3
// c4._nonNullCField._cField._nonNullCField._cField.ToString(); // warn
7 8 9
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c4._nonNullCField._cField._nonNullCField._cField").WithLocation(59, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c4._nonNullCField._cField._nonNullCField._cField").WithLocation(59, 13),
// (67,13): warning CS8602: Possible dereference of a null reference.
// (67,13): warning CS8602: Possible dereference of a null reference.
// c5._cField.ToString(); // warn
x2
// c5._cField.ToString(); // warn
10 11
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c5").WithLocation(67, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c5").WithLocation(67, 13),
// (67,13): warning CS8602: Possible dereference of a null reference.
// (67,13): warning CS8602: Possible dereference of a null reference.
// c5._cField.ToString(); // warn
x2
// c5._cField.ToString(); // warn
10 11
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c5._cField").WithLocation(67, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c5._cField").WithLocation(67, 13),
// (79,13): warning CS8602: Possible dereference of a null reference.
// (79,13): warning CS8602: Possible dereference of a null reference.
// c6._cField.GetC().ToString(); // warn
// c6._cField.GetC().ToString(); // warn
12
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c6._cField.GetC()").WithLocation(79, 13)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c6._cField.GetC()").WithLocation(79, 13)
);
);
}
}
...
@@ -11888,11 +11889,11 @@ void Test(C? c1)
...
@@ -11888,11 +11889,11 @@ void Test(C? c1)
if (c1?[0] != null)
if (c1?[0] != null)
{
{
c1.ToString();
c1.ToString();
c1[0].ToString(); // warn
c1[0].ToString(); // warn
1
}
}
else
else
{
{
c1.ToString(); // warn
c1.ToString(); // warn
2
}
}
}
}
...
@@ -11902,14 +11903,75 @@ void Test(C? c1)
...
@@ -11902,14 +11903,75 @@ void Test(C? c1)
compilation.VerifyDiagnostics(
compilation.VerifyDiagnostics(
// (9,13): warning CS8602: Possible dereference of a null reference.
// (9,13): warning CS8602: Possible dereference of a null reference.
// c1[0].ToString(); // warn
// c1[0].ToString(); // warn
1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1[0]").WithLocation(9, 13),
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1[0]").WithLocation(9, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// (13,13): warning CS8602: Possible dereference of a null reference.
// c1.ToString(); // warn
// c1.ToString(); // warn
2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1").WithLocation(13, 13)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1").WithLocation(13, 13)
);
);
}
}
[Fact]
public void ConditionalBranching_16()
{
var compilation = CreateCompilation(@"
class C
{
void Test<T>(T t)
{
if (t?.ToString() != null)
{
t.ToString();
}
else
{
t.ToString(); // warn
}
}
}", parseOptions: TestOptions.Regular8);
// PROTOTYPE(NullableReferenceTypes): We are currently warning on all unconstrained type parameter invocations
// https://github.com/dotnet/roslyn/issues/28792
compilation.VerifyDiagnostics(
// (6,13): warning CS8602: Possible dereference of a null reference.
// if (t?.ToString() != null)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t").WithLocation(6, 13),
// (8,13): warning CS8602: Possible dereference of a null reference.
// t.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t").WithLocation(8, 13),
// (12,13): warning CS8602: Possible dereference of a null reference.
// t.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t").WithLocation(12, 13)
);
}
[Fact]
public void ConditionalBranching_17()
{
var compilation = CreateCompilation(@"
class C
{
object? Prop { get; }
object? GetObj(bool val) => null;
void Test(C? c1, C? c2)
{
if (c1?.GetObj(c2?.Prop != null) != null)
{
c2.Prop.ToString(); // warn 1 2
}
}
}", parseOptions: TestOptions.Regular8);
compilation.VerifyDiagnostics(
// (10,13): warning CS8602: Possible dereference of a null reference.
// c2.Prop.ToString(); // warn 1 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c2").WithLocation(10, 13),
// (10,13): warning CS8602: Possible dereference of a null reference.
// c2.Prop.ToString(); // warn 1 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c2.Prop").WithLocation(10, 13)
);
}
[Fact]
[Fact]
public void ConditionalOperator_01()
public void ConditionalOperator_01()
{
{
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录