-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathJ.cs
More file actions
146 lines (119 loc) · 3.52 KB
/
J.cs
File metadata and controls
146 lines (119 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
namespace System.Runtime.CompilerServices
{
internal static class IsExternalInit { }
}
public record class RecordClass(object Prop1, object Prop2) { }
public record struct RecordStruct(object Prop1, object Prop2) { }
public struct Struct
{
public object Field;
public object Prop { get; init; }
public Struct(object field, object prop) => (Field, Prop) = (field, prop);
}
public class J
{
private void M1()
{
var o = Source<object>(1);
var r1 = new RecordClass(o, null);
Sink(r1.Prop1); // $ hasValueFlow=1
Sink(r1.Prop2); // no flow
var r2 = r1 with { };
Sink(r2.Prop1); // $ hasValueFlow=1
Sink(r2.Prop2); // no flow
var r3 = r1 with { Prop2 = Source<object>(2) };
Sink(r3.Prop1); // $ hasValueFlow=1
Sink(r3.Prop2); // $ hasValueFlow=2
var r4 = r1 with { Prop1 = null };
Sink(r4.Prop1); // no flow
Sink(r4.Prop2); // no flow
}
private void M2()
{
var o = Source<object>(2);
var r1 = new RecordStruct(o, null);
Sink(r1.Prop1); // $ hasValueFlow=2
Sink(r1.Prop2); // no flow
var r2 = r1 with { };
Sink(r2.Prop1); // $ hasValueFlow=2
Sink(r2.Prop2); // no flow
var r3 = r1 with { Prop2 = Source<object>(3) };
Sink(r3.Prop1); // $ hasValueFlow=2
Sink(r3.Prop2); // $ hasValueFlow=3
var r4 = r1 with { Prop1 = null };
Sink(r4.Prop1); // no flow
Sink(r4.Prop2); // no flow
}
private void M3()
{
var o = Source<object>(3);
var s1 = new Struct(o, null);
var s2 = s1 with { };
Sink(s2.Field); // $ hasValueFlow=3
Sink(s2.Prop); // no flow
var s3 = s1 with { Prop = Source<object>(4) };
Sink(s3.Field); // $ hasValueFlow=3
Sink(s3.Prop); // $ hasValueFlow=4
var s4 = s1 with { Field = null };
Sink(s4.Field); // no flow
Sink(s4.Prop); // no flow
}
private void M4()
{
var o = Source<object>(5);
var s1 = new Struct(null, o);
var s2 = s1 with { };
Sink(s2.Field); // $ no flow
Sink(s2.Prop); // $ hasValueFlow=5
var s3 = s1 with { Field = Source<object>(6) };
Sink(s3.Field); // $ hasValueFlow=6
Sink(s3.Prop); // $ hasValueFlow=5
var s4 = s1 with { Prop = null };
Sink(s4.Field); // no flow
Sink(s4.Prop); // no flow
}
private void M5()
{
var o = Source<object>(7);
object @null = null;
var a1 = new { X = o, Y = @null };
var a2 = a1 with { };
Sink(a2.X); // $ hasValueFlow=7
Sink(a2.Y); // no flow
var a3 = a1 with { Y = Source<object>(8) };
Sink(a3.X); // $ hasValueFlow=7
Sink(a3.Y); // $ hasValueFlow=8
var a4 = a1 with { X = @null };
Sink(a4.X); // no flow
Sink(a4.Y); // no flow
}
private void M6(bool b)
{
var a = new int[1];
if (b)
{
a[0] = Source<int>(10);
}
else
{
a = new int[1];
}
Sink(a[0]); // $ hasValueFlow=10
}
private void M7(bool b)
{
var a = new System.Collections.Generic.List<int>();
if (b)
{
a.Add(Source<int>(11));
a.Clear();
}
else
{
a = new System.Collections.Generic.List<int>();
}
Sink(a[0]);
}
public static void Sink(object o) { }
static T Source<T>(object source) => throw null;
}