-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sema: fix safe integer arithmetic operations on undefined values
Previously `@as(i64, undefined) +% 1` would produce `@as(@typeof(undefined), undefined)` which now gives `@as(i64, undefined)`. Previously `@as(i64, undefined) +| 1` would hit an assertion which now gives `@as(i64, undefined)`.
- Loading branch information
Showing
10 changed files
with
261 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,24 @@ | ||
comptime { | ||
const a: i64 = undefined; | ||
_ = a + a; | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If either of the operands are zero, then the other operand is returned. | ||
@compileLog(undef + 0); | ||
@compileLog(not_undef + 0); | ||
@compileLog(0 + undef); | ||
@compileLog(0 + not_undef); | ||
|
||
_ = undef + undef; | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :3:13: error: use of undefined value here causes undefined behavior | ||
// :11:17: error: use of undefined value here causes undefined behavior | ||
// | ||
// Compile Log Output: | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
comptime { | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If either of the operands are zero, then the other operand is returned. | ||
@compileLog(undef +| 0); | ||
@compileLog(not_undef +| 0); | ||
@compileLog(0 +| undef); | ||
@compileLog(0 +| not_undef); | ||
// If either of the operands are undefined, the result is undefined. | ||
@compileLog(undef +| 1); | ||
@compileLog(not_undef +| 1); | ||
@compileLog(1 +| undef); | ||
@compileLog(1 +| not_undef); | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :6:5: error: found compile log statement | ||
// | ||
// Compile Log Output: | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 33) | ||
// @as(i64, undefined) | ||
// @as(i64, 33) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
comptime { | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If either of the operands are zero, then the other operand is returned. | ||
@compileLog(undef +% 0); | ||
@compileLog(not_undef +% 0); | ||
@compileLog(0 +% undef); | ||
@compileLog(0 +% not_undef); | ||
// If either of the operands are undefined, the result is undefined. | ||
@compileLog(undef +% 1); | ||
@compileLog(not_undef +% 1); | ||
@compileLog(1 +% undef); | ||
@compileLog(1 +% not_undef); | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :6:5: error: found compile log statement | ||
// | ||
// Compile Log Output: | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 33) | ||
// @as(i64, undefined) | ||
// @as(i64, 33) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,38 @@ | ||
comptime { | ||
const a: i64 = undefined; | ||
_ = a * a; | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If either of the operands are zero, the result is zero. | ||
@compileLog(undef * 0); | ||
@compileLog(not_undef * 0); | ||
@compileLog(0 * undef); | ||
@compileLog(0 * not_undef); | ||
|
||
// If either of the operands are one, the result is the other | ||
// operand, even if it is undefined. | ||
@compileLog(undef * 1); | ||
@compileLog(not_undef * 1); | ||
@compileLog(1 * undef); | ||
@compileLog(1 * not_undef); | ||
|
||
// If either of the operands are undefined, it's a compile error | ||
// because there is a possible value for which the addition would | ||
// overflow (max_int), causing illegal behavior. | ||
_ = undef * undef; | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :3:13: error: use of undefined value here causes undefined behavior | ||
// :21:17: error: use of undefined value here causes undefined behavior | ||
// | ||
// Compile Log Output: | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
comptime { | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If either of the operands are zero, the result is zero. | ||
@compileLog(undef *| 0); | ||
@compileLog(not_undef *| 0); | ||
@compileLog(0 *| undef); | ||
@compileLog(0 *| not_undef); | ||
|
||
// If either of the operands are one, result is the other operand. | ||
@compileLog(undef *| 1); | ||
@compileLog(not_undef *| 1); | ||
@compileLog(1 *| undef); | ||
@compileLog(1 *| not_undef); | ||
|
||
// If either of the operands are undefined, result is undefined. | ||
@compileLog(undef *| 2); | ||
@compileLog(2 *| undef); | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :6:5: error: found compile log statement | ||
// | ||
// Compile Log Output: | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, undefined) |
38 changes: 38 additions & 0 deletions
38
test/cases/compile_errors/mult_wrap_on_undefined_value.zig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
comptime { | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If either of the operands are zero, the result is zero. | ||
@compileLog(undef *% 0); | ||
@compileLog(not_undef *% 0); | ||
@compileLog(0 *% undef); | ||
@compileLog(0 *% not_undef); | ||
|
||
// If either of the operands are one, result is the other operand. | ||
@compileLog(undef *% 1); | ||
@compileLog(not_undef *% 1); | ||
@compileLog(1 *% undef); | ||
@compileLog(1 *% not_undef); | ||
|
||
// If either of the operands are undefined, result is undefined. | ||
@compileLog(undef *% 2); | ||
@compileLog(2 *% undef); | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :6:5: error: found compile log statement | ||
// | ||
// Compile Log Output: | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, 0) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, undefined) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,20 @@ | ||
comptime { | ||
const a: i64 = undefined; | ||
_ = a - a; | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If the rhs is zero, then the other operand is returned, even if it is undefined. | ||
@compileLog(undef - 0); | ||
@compileLog(not_undef - 0); | ||
|
||
_ = undef - undef; | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :3:13: error: use of undefined value here causes undefined behavior | ||
// :9:17: error: use of undefined value here causes undefined behavior | ||
// | ||
// Compile Log Output: | ||
// @as(i64, undefined) | ||
// @as(i64, 32) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
comptime { | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If the RHS is zero, then the LHS is returned, even if it is undefined. | ||
@compileLog(undef -| 0); | ||
@compileLog(not_undef -| 0); | ||
// If either of the operands are undefined, the result is undefined. | ||
@compileLog(undef -| not_undef); | ||
@compileLog(not_undef -| undef); | ||
@compileLog(undef -| undef); | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :6:5: error: found compile log statement | ||
// | ||
// Compile Log Output: | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, undefined) | ||
// @as(i64, undefined) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
comptime { | ||
const undef: i64 = undefined; | ||
const not_undef: i64 = 32; | ||
|
||
// If the RHS is zero, then the LHS is returned, even if it is undefined. | ||
@compileLog(undef -% 0); | ||
@compileLog(not_undef -% 0); | ||
// If either of the operands are undefined, the result is undefined. | ||
@compileLog(undef -% not_undef); | ||
@compileLog(not_undef -% undef); | ||
@compileLog(undef -% undef); | ||
} | ||
|
||
// error | ||
// backend=stage2 | ||
// target=native | ||
// | ||
// :6:5: error: found compile log statement | ||
// | ||
// Compile Log Output: | ||
// @as(i64, undefined) | ||
// @as(i64, 32) | ||
// @as(i64, undefined) | ||
// @as(i64, undefined) | ||
// @as(i64, undefined) |