Skip to content

Commit 10ac8b4

Browse files
authored
Merge pull request #22022 from Kingwl/enum-eval-div-zero
disallow nan and infinity in enum member
2 parents e0c1d07 + 45e6df9 commit 10ac8b4

File tree

6 files changed

+262
-3
lines changed

6 files changed

+262
-3
lines changed

src/compiler/checker.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -24752,7 +24752,11 @@ namespace ts {
2475224752
case SyntaxKind.ParenthesizedExpression:
2475324753
return evaluate((<ParenthesizedExpression>expr).expression);
2475424754
case SyntaxKind.Identifier:
24755-
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), (<Identifier>expr).escapedText);
24755+
const identifier = <Identifier>expr;
24756+
if (isInfinityOrNaNString(identifier.escapedText)) {
24757+
return +(identifier.escapedText);
24758+
}
24759+
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText);
2475624760
case SyntaxKind.ElementAccessExpression:
2475724761
case SyntaxKind.PropertyAccessExpression:
2475824762
const ex = <PropertyAccessExpression | ElementAccessExpression>expr;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
tests/cases/conformance/enums/enumConstantMembers.ts(32,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
2+
tests/cases/conformance/enums/enumConstantMembers.ts(33,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
3+
tests/cases/conformance/enums/enumConstantMembers.ts(34,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
4+
tests/cases/conformance/enums/enumConstantMembers.ts(35,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
5+
tests/cases/conformance/enums/enumConstantMembers.ts(36,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
6+
tests/cases/conformance/enums/enumConstantMembers.ts(37,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
7+
tests/cases/conformance/enums/enumConstantMembers.ts(38,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
8+
9+
10+
==== tests/cases/conformance/enums/enumConstantMembers.ts (7 errors) ====
11+
// Constant members allow negatives, but not decimals. Also hex literals are allowed
12+
enum E1 {
13+
a = 1,
14+
b
15+
}
16+
enum E2 {
17+
a = - 1,
18+
b
19+
}
20+
enum E3 {
21+
a = 0.1,
22+
b // Error because 0.1 is not a constant
23+
}
24+
25+
declare enum E4 {
26+
a = 1,
27+
b = -1,
28+
c = 0.1 // Not a constant
29+
}
30+
31+
enum E5 {
32+
a = 1 / 0,
33+
b = 2 / 0.0,
34+
c = 1.0 / 0.0,
35+
d = 0.0 / 0.0,
36+
e = NaN,
37+
f = Infinity,
38+
g = -Infinity
39+
}
40+
41+
const enum E6 {
42+
a = 1 / 0,
43+
~~~~~
44+
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
45+
b = 2 / 0.0,
46+
~~~~~~~
47+
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
48+
c = 1.0 / 0.0,
49+
~~~~~~~~~
50+
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
51+
d = 0.0 / 0.0,
52+
~~~~~~~~~
53+
!!! error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
54+
e = NaN,
55+
~~~
56+
!!! error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'.
57+
f = Infinity,
58+
~~~~~~~~
59+
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
60+
g = -Infinity
61+
~~~~~~~~~
62+
!!! error TS2477: 'const' enum member initializer was evaluated to a non-finite value.
63+
}
64+

tests/baselines/reference/enumConstantMembers.js

+32-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,28 @@ declare enum E4 {
1717
a = 1,
1818
b = -1,
1919
c = 0.1 // Not a constant
20-
}
20+
}
21+
22+
enum E5 {
23+
a = 1 / 0,
24+
b = 2 / 0.0,
25+
c = 1.0 / 0.0,
26+
d = 0.0 / 0.0,
27+
e = NaN,
28+
f = Infinity,
29+
g = -Infinity
30+
}
31+
32+
const enum E6 {
33+
a = 1 / 0,
34+
b = 2 / 0.0,
35+
c = 1.0 / 0.0,
36+
d = 0.0 / 0.0,
37+
e = NaN,
38+
f = Infinity,
39+
g = -Infinity
40+
}
41+
2142

2243
//// [enumConstantMembers.js]
2344
// Constant members allow negatives, but not decimals. Also hex literals are allowed
@@ -36,3 +57,13 @@ var E3;
3657
E3[E3["a"] = 0.1] = "a";
3758
E3[E3["b"] = 1.1] = "b"; // Error because 0.1 is not a constant
3859
})(E3 || (E3 = {}));
60+
var E5;
61+
(function (E5) {
62+
E5[E5["a"] = Infinity] = "a";
63+
E5[E5["b"] = Infinity] = "b";
64+
E5[E5["c"] = Infinity] = "c";
65+
E5[E5["d"] = NaN] = "d";
66+
E5[E5["e"] = NaN] = "e";
67+
E5[E5["f"] = Infinity] = "f";
68+
E5[E5["g"] = -Infinity] = "g";
69+
})(E5 || (E5 = {}));

tests/baselines/reference/enumConstantMembers.symbols

+57
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,60 @@ declare enum E4 {
4040
c = 0.1 // Not a constant
4141
>c : Symbol(E4.c, Decl(enumConstantMembers.ts, 16, 11))
4242
}
43+
44+
enum E5 {
45+
>E5 : Symbol(E5, Decl(enumConstantMembers.ts, 18, 1))
46+
47+
a = 1 / 0,
48+
>a : Symbol(E5.a, Decl(enumConstantMembers.ts, 20, 9))
49+
50+
b = 2 / 0.0,
51+
>b : Symbol(E5.b, Decl(enumConstantMembers.ts, 21, 14))
52+
53+
c = 1.0 / 0.0,
54+
>c : Symbol(E5.c, Decl(enumConstantMembers.ts, 22, 16))
55+
56+
d = 0.0 / 0.0,
57+
>d : Symbol(E5.d, Decl(enumConstantMembers.ts, 23, 18))
58+
59+
e = NaN,
60+
>e : Symbol(E5.e, Decl(enumConstantMembers.ts, 24, 18))
61+
>NaN : Symbol(NaN, Decl(lib.d.ts, --, --))
62+
63+
f = Infinity,
64+
>f : Symbol(E5.f, Decl(enumConstantMembers.ts, 25, 12))
65+
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
66+
67+
g = -Infinity
68+
>g : Symbol(E5.g, Decl(enumConstantMembers.ts, 26, 17))
69+
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
70+
}
71+
72+
const enum E6 {
73+
>E6 : Symbol(E6, Decl(enumConstantMembers.ts, 28, 1))
74+
75+
a = 1 / 0,
76+
>a : Symbol(E6.a, Decl(enumConstantMembers.ts, 30, 15))
77+
78+
b = 2 / 0.0,
79+
>b : Symbol(E6.b, Decl(enumConstantMembers.ts, 31, 14))
80+
81+
c = 1.0 / 0.0,
82+
>c : Symbol(E6.c, Decl(enumConstantMembers.ts, 32, 16))
83+
84+
d = 0.0 / 0.0,
85+
>d : Symbol(E6.d, Decl(enumConstantMembers.ts, 33, 18))
86+
87+
e = NaN,
88+
>e : Symbol(E6.e, Decl(enumConstantMembers.ts, 34, 18))
89+
>NaN : Symbol(NaN, Decl(lib.d.ts, --, --))
90+
91+
f = Infinity,
92+
>f : Symbol(E6.f, Decl(enumConstantMembers.ts, 35, 12))
93+
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
94+
95+
g = -Infinity
96+
>g : Symbol(E6.g, Decl(enumConstantMembers.ts, 36, 17))
97+
>Infinity : Symbol(Infinity, Decl(lib.d.ts, --, --))
98+
}
99+

tests/baselines/reference/enumConstantMembers.types

+83
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,86 @@ declare enum E4 {
4848
>c : E4.c
4949
>0.1 : 0.1
5050
}
51+
52+
enum E5 {
53+
>E5 : E5
54+
55+
a = 1 / 0,
56+
>a : E5
57+
>1 / 0 : number
58+
>1 : 1
59+
>0 : 0
60+
61+
b = 2 / 0.0,
62+
>b : E5
63+
>2 / 0.0 : number
64+
>2 : 2
65+
>0.0 : 0
66+
67+
c = 1.0 / 0.0,
68+
>c : E5
69+
>1.0 / 0.0 : number
70+
>1.0 : 1
71+
>0.0 : 0
72+
73+
d = 0.0 / 0.0,
74+
>d : E5
75+
>0.0 / 0.0 : number
76+
>0.0 : 0
77+
>0.0 : 0
78+
79+
e = NaN,
80+
>e : E5
81+
>NaN : number
82+
83+
f = Infinity,
84+
>f : E5
85+
>Infinity : number
86+
87+
g = -Infinity
88+
>g : E5
89+
>-Infinity : number
90+
>Infinity : number
91+
}
92+
93+
const enum E6 {
94+
>E6 : E6
95+
96+
a = 1 / 0,
97+
>a : E6
98+
>1 / 0 : number
99+
>1 : 1
100+
>0 : 0
101+
102+
b = 2 / 0.0,
103+
>b : E6
104+
>2 / 0.0 : number
105+
>2 : 2
106+
>0.0 : 0
107+
108+
c = 1.0 / 0.0,
109+
>c : E6
110+
>1.0 / 0.0 : number
111+
>1.0 : 1
112+
>0.0 : 0
113+
114+
d = 0.0 / 0.0,
115+
>d : E6
116+
>0.0 / 0.0 : number
117+
>0.0 : 0
118+
>0.0 : 0
119+
120+
e = NaN,
121+
>e : E6
122+
>NaN : number
123+
124+
f = Infinity,
125+
>f : E6
126+
>Infinity : number
127+
128+
g = -Infinity
129+
>g : E6
130+
>-Infinity : number
131+
>Infinity : number
132+
}
133+

tests/cases/conformance/enums/enumConstantMembers.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,24 @@ declare enum E4 {
1616
a = 1,
1717
b = -1,
1818
c = 0.1 // Not a constant
19-
}
19+
}
20+
21+
enum E5 {
22+
a = 1 / 0,
23+
b = 2 / 0.0,
24+
c = 1.0 / 0.0,
25+
d = 0.0 / 0.0,
26+
e = NaN,
27+
f = Infinity,
28+
g = -Infinity
29+
}
30+
31+
const enum E6 {
32+
a = 1 / 0,
33+
b = 2 / 0.0,
34+
c = 1.0 / 0.0,
35+
d = 0.0 / 0.0,
36+
e = NaN,
37+
f = Infinity,
38+
g = -Infinity
39+
}

0 commit comments

Comments
 (0)