@@ -4,12 +4,22 @@ public class Operators
4
4
static void Sink ( object o ) { }
5
5
static T Source < T > ( object source ) => throw null ;
6
6
7
- public class C
7
+ public interface I < T > where T : I < T >
8
+ {
9
+ static virtual T operator * ( T x , T y ) => x ;
10
+ static abstract T operator / ( T x , T y ) ;
11
+ static abstract T operator checked / ( T x , T y ) ;
12
+ }
13
+
14
+ public class C : I < C >
8
15
{
9
16
public static C operator + ( C x , C y ) => x ;
10
17
11
18
public static C operator checked - ( C x , C y ) => y ;
12
19
public static C operator - ( C x , C y ) => x ;
20
+
21
+ public static C operator / ( C x , C y ) => y ;
22
+ public static C operator checked / ( C x , C y ) => y ;
13
23
}
14
24
15
25
public void M1 ( )
@@ -35,4 +45,43 @@ public void M3()
35
45
var z = checked ( x - y ) ;
36
46
Sink ( z ) ; // $ hasValueFlow=6
37
47
}
48
+
49
+ public void M4Aux < T > ( T x , T y ) where T : I < T >
50
+ {
51
+ var z = x * y ;
52
+ Sink ( z ) ; // $ hasValueFlow=7
53
+ }
54
+
55
+ public void M4 ( )
56
+ {
57
+ var x = Source < C > ( 7 ) ;
58
+ var y = Source < C > ( 8 ) ;
59
+ M4Aux ( x , y ) ;
60
+ }
61
+
62
+ public void M5Aux < T > ( T x , T y ) where T : I < T >
63
+ {
64
+ var z = x / y ;
65
+ Sink ( z ) ; // $ hasValueFlow=10
66
+ }
67
+
68
+ public void M5 ( )
69
+ {
70
+ var x = Source < C > ( 9 ) ;
71
+ var y = Source < C > ( 10 ) ;
72
+ M5Aux ( x , y ) ;
73
+ }
74
+
75
+ public void M6Aux < T > ( T x , T y ) where T : I < T >
76
+ {
77
+ var z = checked ( x / y ) ;
78
+ Sink ( z ) ; // $ hasValueFlow=12
79
+ }
80
+
81
+ public void M6 ( )
82
+ {
83
+ var x = Source < C > ( 11 ) ;
84
+ var y = Source < C > ( 12 ) ;
85
+ M6Aux ( x , y ) ;
86
+ }
38
87
}
0 commit comments