-
-
Notifications
You must be signed in to change notification settings - Fork 415
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It generates incorrect LLVM IR in some scenarios and can also lead to compiler crashes. Fixes #4464
- Loading branch information
1 parent
7705105
commit b9f3b6b
Showing
6 changed files
with
81 additions
and
21 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
## Disallow `return` at the end of a `with` block | ||
|
||
When we reimplemented `with` blocks in 2022, we allowed the usage of `return` at the end of the block. Recent analysis of the generated LLVM flagged incorrect LLVM IR that was generated from such code. | ||
|
||
Upon review, we realized that `return` at the end of a `with` block should be disallowed in the same way that `return` at the end of a method is disallowed. | ||
|
||
This a breaking change. If you had code such as: | ||
|
||
```pony | ||
actor Main | ||
new create(env: Env) => | ||
with d = Disposble do | ||
d.set_exit(10) | ||
return | ||
end | ||
``` | ||
|
||
You'll need to update it to: | ||
|
||
```pony | ||
actor Main | ||
new create(env: Env) => | ||
with d = Disposble do | ||
d.set_exit(10) | ||
end | ||
``` | ||
|
||
The above examples are semantically the same. This also fixes a compiler crash if you had something along the lines of: | ||
|
||
```pony | ||
actor Main | ||
new create(env: Env) => | ||
with d = Disposble do | ||
d.set_exit(10) | ||
return | ||
end | ||
let x = "foo" | ||
``` | ||
|
||
Where you had code "after the return" which would be unexpected by the compiler. |
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 was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include <gtest/gtest.h> | ||
#include <platform.h> | ||
|
||
#include "util.h" | ||
|
||
|
||
#define TEST_COMPILE(src) DO(test_compile(src, "expr")) | ||
|
||
#define TEST_ERRORS_1(src, err1) \ | ||
{ const char* errs[] = {err1, NULL}; \ | ||
DO(test_expected_errors(src, "expr", errs)); } | ||
|
||
class WithTest : public PassTest | ||
{}; | ||
|
||
TEST_F(WithTest, NoEarlyReturnFromWith) | ||
{ | ||
// From issue #4464 | ||
const char* src = | ||
"class Disposable\n" | ||
" new create() => None\n" | ||
" fun ref set_exit(x: U32) => None\n" | ||
" fun dispose() => None\n" | ||
"actor Main\n" | ||
" new create(env: Env) =>\n" | ||
" with d = Disposable do\n" | ||
" d.set_exit(10)\n" | ||
" return\n" | ||
" end"; | ||
|
||
TEST_ERRORS_1(src, | ||
"use return only to exit early from a with block, not at the end"); | ||
} |