Skip to content

Commit

Permalink
fix: return-statement reachability analysis (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-trunov authored Apr 26, 2024
1 parent e3196b7 commit 040e648
Show file tree
Hide file tree
Showing 18 changed files with 429 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Tact's CLI returns a non-zero exit code if compilation fails: PR [#278](https://github.com/tact-lang/tact/pull/278)
- Use the most recent version of the FunC standard library [`stdlib.fc`](https://github.com/ton-blockchain/ton/blob/4cfe1d1a96acf956e28e2bbc696a143489e23631/crypto/smartcont/stdlib.fc): PR [#283](https://github.com/tact-lang/tact/pull/283)
- The WASM version of the FunC compiler has been updated to 0.4.4 and patched to work on larger contracts: PR [#297](https://github.com/tact-lang/tact/pull/297)
- The `return`-statement reachability analysis: PR [#302](https://github.com/tact-lang/tact/pull/302)

## [1.2.0] - 2024-02-29

Expand Down
1 change: 0 additions & 1 deletion src/test/features/try-catch.tact
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ contract TryCatchTester {
} catch (e) {
return e;
}
return 0;
}

get fun testTryCatch3(): Int {
Expand Down
220 changes: 220 additions & 0 deletions src/types/__snapshots__/resolveStatements.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,96 @@ Line 6, col 5:
"
`;
exports[`resolveStatements should fail statements for case-38 1`] = `
"<unknown>:6:5: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 6, col 5:
5 | contract Foo {
> 6 | get fun noReturn(): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~
7 | // ERROR: no return statement
"
`;
exports[`resolveStatements should fail statements for case-39 1`] = `
"<unknown>:6:5: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 6, col 5:
5 | contract Foo {
> 6 | get fun noReturn(): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~
7 | let x: Int = 42;
"
`;
exports[`resolveStatements should fail statements for case-40 1`] = `
"<unknown>:6:5: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 6, col 5:
5 | contract Foo {
> 6 | get fun notAlwaysReachableReturn(b: Bool): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 | if b {
"
`;
exports[`resolveStatements should fail statements for case-41 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 4, col 1:
3 |
> 4 | fun notAlwaysReachableReturn(b: Bool): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | if (b) {
"
`;
exports[`resolveStatements should fail statements for case-42 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 4, col 1:
3 |
> 4 | fun notAlwaysReachableReturn(b: Bool): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | try {
"
`;
exports[`resolveStatements should fail statements for case-43 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 4, col 1:
3 |
> 4 | fun notAlwaysReachableReturn(b: Bool): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | try {
"
`;
exports[`resolveStatements should fail statements for case-44 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 4, col 1:
3 |
> 4 | fun notAlwaysReachableReturn(b: Bool): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | while (b) {
"
`;
exports[`resolveStatements should fail statements for case-45 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 4, col 1:
3 |
> 4 | fun notAlwaysReachableReturn(n: Int): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | repeat (n) {
"
`;
exports[`resolveStatements should fail statements for case-46 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
Line 4, col 1:
3 |
> 4 | fun notAlwaysReachableReturn(b: Bool): Int {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | do {
"
`;
exports[`resolveStatements should resolve statements for case-0 1`] = `
[
[
Expand Down Expand Up @@ -1106,3 +1196,133 @@ exports[`resolveStatements should resolve statements for case-15 1`] = `
],
]
`;
exports[`resolveStatements should resolve statements for case-16 1`] = `[]`;
exports[`resolveStatements should resolve statements for case-17 1`] = `
[
[
"42",
"Int",
],
[
"x",
"Int",
],
[
"1",
"Int",
],
]
`;
exports[`resolveStatements should resolve statements for case-18 1`] = `
[
[
"b",
"Bool",
],
[
"42",
"Int",
],
[
"c",
"Bool",
],
[
"43",
"Int",
],
[
"d",
"Bool",
],
[
"44",
"Int",
],
[
"45",
"Int",
],
]
`;
exports[`resolveStatements should resolve statements for case-19 1`] = `
[
[
"0",
"Int",
],
[
"1",
"Int",
],
[
"42",
"Int",
],
[
"1",
"Int",
],
[
"43",
"Int",
],
]
`;
exports[`resolveStatements should resolve statements for case-20 1`] = `
[
[
"b",
"Bool",
],
[
"1",
"Int",
],
[
"b",
"Bool",
],
[
"0",
"Int",
],
[
"1",
"Int",
],
[
"b ? 0 : 1",
"Int",
],
[
"1 / (b ? 0 : 1)",
"Int",
],
[
"42",
"Int",
],
[
"43",
"Int",
],
[
"b",
"Bool",
],
[
"!b",
"Bool",
],
[
"44",
"Int",
],
]
`;
Loading

0 comments on commit 040e648

Please sign in to comment.