Skip to content

Commit 495814f

Browse files
authored
fix: Fix invalid codegen on small to long int cast (#1921)
1 parent ad009d3 commit 495814f

10 files changed

+940
-13
lines changed

Diff for: src/compiler.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3521,10 +3521,10 @@ export class Compiler extends DiagnosticEmitter {
35213521
if (currentType != contextualType.nonNullableType) { // allow assigning non-nullable to nullable
35223522
if (constraints & Constraints.CONV_EXPLICIT) {
35233523
expr = this.convertExpression(expr, currentType, contextualType, true, expression);
3524-
this.currentType = contextualType;
3524+
this.currentType = currentType = contextualType;
35253525
} else if (constraints & Constraints.CONV_IMPLICIT) {
35263526
expr = this.convertExpression(expr, currentType, contextualType, false, expression);
3527-
this.currentType = contextualType;
3527+
this.currentType = currentType = contextualType;
35283528
}
35293529
}
35303530
if (wrap) expr = this.ensureSmallIntegerWrap(expr, currentType);

Diff for: src/flow.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,13 @@ export class Flow {
13511351
case UnaryOp.ClzI32:
13521352
case UnaryOp.CtzI32:
13531353
case UnaryOp.PopcntI32: return type.size < 7;
1354+
1355+
// sign extensions overflow if result can have high garbage bits in the target type
1356+
case UnaryOp.Extend8I32: return type.size < (type.isUnsignedIntegerValue ? 32 : 8);
1357+
case UnaryOp.Extend8I64: return type.size < (type.isUnsignedIntegerValue ? 64 : 8);
1358+
case UnaryOp.Extend16I32: return type.size < (type.isUnsignedIntegerValue ? 32 : 16);
1359+
case UnaryOp.Extend16I64: return type.size < (type.isUnsignedIntegerValue ? 64 : 16);
1360+
case UnaryOp.Extend32I64: return type.size < (type.isUnsignedIntegerValue ? 64 : 32);
13541361
}
13551362
break;
13561363
}

Diff for: tests/compiler/abi.untouched.wat

-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@
8888
local.set $0
8989
end
9090
local.get $0
91-
i32.extend8_s
9291
i32.eqz
9392
i32.eqz
9493
if
@@ -176,7 +175,6 @@
176175
)
177176
(func $abi/exportedExported (result i32)
178177
call $abi/exported
179-
i32.extend8_s
180178
)
181179
(func $abi/exportedInternal (result i32)
182180
call $abi/internal

Diff for: tests/compiler/cast.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"asc_flags": [
3+
]
4+
}

Diff for: tests/compiler/cast.optimized.wat

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(module
2+
(memory $0 0)
3+
(export "memory" (memory $0))
4+
)

Diff for: tests/compiler/cast.ts

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
function test<T,U>(x: T): U {
2+
// @ts-ignore
3+
var y = x as U;
4+
// @ts-ignore
5+
return y;
6+
}
7+
8+
test<i8,i8>(0);
9+
test<i8,u8>(0);
10+
test<i8,i16>(0);
11+
test<i8,u16>(0);
12+
test<i8,i32>(0);
13+
test<i8,u32>(0);
14+
test<i8,i64>(0);
15+
test<i8,u64>(0);
16+
test<i8,bool>(0);
17+
18+
test<u8,i8>(0);
19+
test<u8,u8>(0);
20+
test<u8,i16>(0);
21+
test<u8,u16>(0);
22+
test<u8,i32>(0);
23+
test<u8,u32>(0);
24+
test<u8,i64>(0);
25+
test<u8,u64>(0);
26+
test<u8,bool>(0);
27+
28+
test<i16,i8>(0);
29+
test<i16,u8>(0);
30+
test<i16,i16>(0);
31+
test<i16,u16>(0);
32+
test<i16,i32>(0);
33+
test<i16,u32>(0);
34+
test<i16,i64>(0);
35+
test<i16,u64>(0);
36+
test<i16,bool>(0);
37+
38+
test<u16,i8>(0);
39+
test<u16,u8>(0);
40+
test<u16,i16>(0);
41+
test<u16,u16>(0);
42+
test<u16,i32>(0);
43+
test<u16,u32>(0);
44+
test<u16,i64>(0);
45+
test<u16,u64>(0);
46+
test<u16,bool>(0);
47+
48+
test<i32,i8>(0);
49+
test<i32,u8>(0);
50+
test<i32,i16>(0);
51+
test<i32,u16>(0);
52+
test<i32,i32>(0);
53+
test<i32,u32>(0);
54+
test<i32,i64>(0);
55+
test<i32,u64>(0);
56+
test<i32,bool>(0);
57+
58+
test<u32,i8>(0);
59+
test<u32,u8>(0);
60+
test<u32,i16>(0);
61+
test<u32,u16>(0);
62+
test<u32,i32>(0);
63+
test<u32,u32>(0);
64+
test<u32,i64>(0);
65+
test<u32,u64>(0);
66+
test<u32,bool>(0);
67+
68+
test<i64,i8>(0);
69+
test<i64,u8>(0);
70+
test<i64,i16>(0);
71+
test<i64,u16>(0);
72+
test<i64,i32>(0);
73+
test<i64,u32>(0);
74+
test<i64,i64>(0);
75+
test<i64,u64>(0);
76+
test<i64,bool>(0);
77+
78+
test<u64,i8>(0);
79+
test<u64,u8>(0);
80+
test<u64,i16>(0);
81+
test<u64,u16>(0);
82+
test<u64,i32>(0);
83+
test<u64,u32>(0);
84+
test<u64,i64>(0);
85+
test<u64,u64>(0);
86+
test<u64,bool>(0);
87+
88+
test<bool,i8>(0);
89+
test<bool,u8>(0);
90+
test<bool,i16>(0);
91+
test<bool,u16>(0);
92+
test<bool,i32>(0);
93+
test<bool,u32>(0);
94+
test<bool,i64>(0);
95+
test<bool,u64>(0);
96+
test<bool,bool>(0);

0 commit comments

Comments
 (0)