-
Notifications
You must be signed in to change notification settings - Fork 263
fix: recognize last uses (including of this
)
#887
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 18 commits
Commits
Show all changes
171 commits
Select commit
Hold shift + click to select a range
709b254
fix(sema): recognize last use immediately after declaration
JohelEGP 1cba29a
fix(sema): give function expression its own scope level
JohelEGP c014679
fix(sema): consider use as function in UFCS call
JohelEGP fc1fa52
refactor(sema): remove stale comment
JohelEGP 286a32e
test(sema): also add unit test for `move` parameter
JohelEGP e3e983b
refactor(sema): avoid possible decrement beyond `begin`
JohelEGP d79b5d7
fix(sema): move `this` on last use
JohelEGP d0fd08d
test: update GCC 13 results
JohelEGP afb57e0
test: add Clang 18 results
JohelEGP a8e84ad
test: add overloads with `that`
JohelEGP 0315e1c
test: add another case that doesn't work yet
JohelEGP a05c514
test: rename members to avoid shadowing
JohelEGP 7f955f6
fix(sema): move implicit `this` of member on last use
JohelEGP 51c80ba
test: remove commented cases that aren't last uses
JohelEGP 257da26
fix(sema): guard check for `move this` parameter once
JohelEGP 6397e20
test: add case for destructor
JohelEGP af66ec0
test: add missing GCC 13 result
JohelEGP d28828e
test: regenerate tests
JohelEGP 0a4ba35
fix(sema): consider use as function in UFCS call
JohelEGP 0ca5fdd
fix(to_cpp1): type-scope variable initialization is not deferred
JohelEGP b212217
refactor(util): add UFCS macros to move and forward
JohelEGP 084fd4a
fix(to_cpp1): emit last use of function in UFCS as part of macro name
JohelEGP 8da1f6d
test: regenerate GCC 13 result
JohelEGP fefe0da
fix(to_cpp1): exercise last use in range of for loop
JohelEGP 545ea22
refactor(util): remove UFCS macros of invalid combinations
JohelEGP 0004512
refactor(to_cpp1): handle range of for loop specifically
JohelEGP e82e9cd
refactor(to_cpp1): consider the expression list range
JohelEGP 1b01804
fix(sema): apply last use to call of member function
JohelEGP d9f5e97
fix(sema): do not move a member function
JohelEGP 7434fd6
fix(to_cpp1): do not move any member function
JohelEGP d78f5d8
test: remove non-problematic comment about double move
JohelEGP 70cb071
refactor: regenerate `reflect.h`
JohelEGP 927077b
refactor(sema): avoid decrementing before begin
JohelEGP aef69a5
fix(sema): extend implicit else branch to containing statement
JohelEGP c364687
fix(sema): increase scope to match an explicit else
JohelEGP f16d2aa
refactor(sema): move heuristic to not change ending depths
JohelEGP c0a8338
fix(sema): pop consecutive implicit else branches
JohelEGP e9cc033
refactor(parse): put implicit else statements in the actual else node
JohelEGP ab792e3
test: add test cases that combine implicit and explicit access
JohelEGP 04f2115
test: add unit test for all test cases as selections
JohelEGP 4d48cc3
fix(reflect): fix initialization and regenerate
JohelEGP 5b6e1fd
fix(sema): apply sema phase to generated code
JohelEGP e0c9019
test: regenerate results
JohelEGP 84296f6
test: add test case for another limitation
JohelEGP f9ec202
test: add another test case that fails
JohelEGP 88591bb
fix(sema): improve heuristic to only move from last (implicit) `this`
JohelEGP 7d72130
refactor(reflect): restore implicit `this` access
JohelEGP 7f4a60f
fix(sema): do not stack an implicit else branch
JohelEGP 0b805d7
refactor: use "implicit scope" throughout
JohelEGP ed9f0f5
fix(sema): use local `move this` to determine last use
JohelEGP 83bd4f0
fix(sema): adjust condition for looking up to type
JohelEGP f9d0859
fix(sema): use last move on called type-scope variable
JohelEGP ba5309f
test: remove bogus comment
JohelEGP 12f2a06
fix(sema): correct unset `this.` case
JohelEGP acd0d8f
test: reference open issue
JohelEGP 73bd215
test: add test cases not affected by the open issue
JohelEGP b359d69
test: clarify FIXME comment
JohelEGP aece9f0
test: review the new tests
JohelEGP 058aa3a
perf: replace `std::map` with `mutable` data member
JohelEGP 3fb7493
refactor: add `symbol::get_final_position`
JohelEGP 4829108
refactor(to_cpp1): do not move single named return
JohelEGP d36d1d2
test: add new test cases to commented out test case
JohelEGP d27307b
test: add similar test case to callable case
JohelEGP c4e06b1
refactor(sema): rework some outdated whitespace
JohelEGP 53bb617
test: regenerate results after "do not move single named return"
JohelEGP 5541a75
feat(sema): diagnose unused variables in generate code
JohelEGP ec568e4
fix(sema): consider variables in type scope declared later
JohelEGP 969aa36
test: refactor new test to use `f_copy`
JohelEGP 33d6adf
refactor(sema): use member token
JohelEGP f1254bf
refactor(sema): update comments
JohelEGP 0e6c378
refactor(sema): use the `this` parameter exclusively
JohelEGP 211d4ba
refactor(sema): update the comments
JohelEGP 20ecbd4
refactor(sema): finish focusing on the implicit 'this'
JohelEGP 36074ba
fix(to_cpp1): move returned uninitialized local
JohelEGP 66837ee
fix(to_cpp1): move single named uninitialized return
JohelEGP 4aa7cf1
test: add case with member declared last
JohelEGP 2532077
refactor(sema): set condition for "at `this.`" correctly
JohelEGP f310ff4
fix(sema): use the better lookup algorithm for this case
JohelEGP 5190062
fix(to_cpp1): stack current names only in namespaces
JohelEGP c7c829e
fix(to_cpp1): stack current names of bases
JohelEGP bea15a5
test: exercise forward in generated code
JohelEGP f632ae6
test: add stand-in for `std::move_only_function`
JohelEGP f628f00
test: remove bogus test case
JohelEGP 30ac563
refactor(to_cpp1): rename to `is_class_member_access`
JohelEGP e42d848
test: add test case showing limitations with base members
JohelEGP e583502
test: actually exercise forward in generated code
JohelEGP cc2b62e
refactor(to_cpp1): reorder branch
JohelEGP 2fca666
refactor(to_cpp1): remove outdated condition
JohelEGP 8f57573
refactor(to_cpp1): rename to `is_class_member_access`
JohelEGP d63a0e2
fix: revert using the empty implicit else branch
JohelEGP 4dc5175
fix(sema): change algorithm to find last uses
JohelEGP 41a34f6
test: add test case for recursion logic
JohelEGP b37e32b
refactor(sema): simplify condition for UFCS on member
JohelEGP 2af060a
test: use `f_inout` and `f_copy` in earlier test cases
JohelEGP 9929d7d
test: enable commented out tests
JohelEGP 18f106e
test: extend limitation unit test with alternative
JohelEGP 27acdba
test: remove redundant explicit discards
JohelEGP 99f5b10
test: add more test cases for the new last use algorithm
JohelEGP 7a5b479
test: add missing `new<int>()`
JohelEGP 80a55aa
fix: regenerate `reflect.h`
JohelEGP 50153c4
test: add test cases of discovered problems
JohelEGP 66d3fc6
fix(sema): pop sibling branch conditions on found last use
JohelEGP 462ab80
refactor(sema): localize variables
JohelEGP b0934e8
fix(sema): recognize uses in iteration statements
JohelEGP e3fe1d0
fix(sema): start from the last symbol, not past-the-end
JohelEGP a8d13a8
refactor(sema): add local type `pos_range`
JohelEGP 34d5f02
fix(sema): handle loops and (non) captures
JohelEGP 249e11c
test: add similar case but without declaration
JohelEGP 650d86f
test: regenerate results
JohelEGP 1fe471f
fix(reflect): update and regenerate `reflect.h`
JohelEGP a963a88
fix(sema): start for loop at its body
JohelEGP 43e7630
refactor(sema): use `std::span`
JohelEGP 1e2d7bc
refactor(sema): register name deactivation at visit
JohelEGP 03a33e6
fix(sema): do not apply use to a hiding name
JohelEGP 0bbe08b
fix(sema): skip hiding loop parameter
JohelEGP 5624c36
test: revert `gcc-version.output`
JohelEGP 5fe3a02
fix(sema): recognize use in _next-clause_
JohelEGP 41fc2eb
test: add corner case
JohelEGP de5df0d
fix(sema): recognize Cpp1 `using` declaration
JohelEGP 10868b0
refactor(sema): avoid adding duplicate symbols
JohelEGP c854c12
refactor(sema): clarify similar members with comments
JohelEGP 0dc41bf
refactor(sema): turn comment into code
JohelEGP 51a81ee
refactor(sema): modify local convenience variable
JohelEGP f1de076
refactor(sema): remove expression scope
JohelEGP ce7c3fa
refactor(sema): use the right predicate
JohelEGP d0c9b15
refactor(sema): remove inactive, stale assertions
JohelEGP d032f9f
refactor(sema): keep using a sentinel
JohelEGP 14f30ee
fix(sema): handle a nested true branch
JohelEGP a064f5f
refactor(sema): revert whitespace change
JohelEGP be1f48a
refactor(sema): fix `started_postfix_expression` simpler
JohelEGP b8b9cac
refactor(sema): revert stale fix of `scope_depth`
JohelEGP 58ed0f2
refactor(sema): comment the need of `final_position` at hand-out
JohelEGP 89941d9
refactor(to_cpp1): drop periods from comment
JohelEGP 095be49
refactor(to_cpp1): reorder arguments for better formatting
JohelEGP 9e0b7c4
refactor(to_cpp1): remove stale non-rvalue context
JohelEGP 4eef0da
refactor(to_cpp1): remove useless non-rvalue context
JohelEGP 06bc83c
refactor(to_cpp1): clarifiy comment with example
JohelEGP 3ad7c88
Merge branch 'main' into last_use
JohelEGP f9ddd78
test: regenerate gcc-13 results
JohelEGP 29fab4a
test: regenerate results
JohelEGP aea6971
refactor(sema): resolve CI issues
JohelEGP 05754b3
test: revert changes to gcc-13 result
JohelEGP a7c1085
refactor: generalize to `identifier_sym::safe_to_move`
JohelEGP 6a77206
test: fix implementation of `identity`
JohelEGP 86b195a
refactor(sema): add scoped indices of uses
JohelEGP 4694545
refactor(sema): simplify names of activation entities
JohelEGP 4f00e57
fix(sema): do not mark non-captures as captures
JohelEGP f61f9f2
refactor(sema): rename to avoid verb prefix
JohelEGP aa6eefe
fix(sema): disable implicit move unsequenced with another use
JohelEGP 430ec9f
fix(sema): consider _is-as-expression_ too
JohelEGP 9e29a61
fix(sema): check all parameters for use
JohelEGP 26a5f49
refactor(sema): remove wrong fix for UFCS issue
JohelEGP c49cba6
Minor updates to compile cppfront and the new test cleanly using MSVC
hsutter 26d71c6
refactor(to_cpp1): pass `0` to `int` parameter instead of `false`
JohelEGP 99f1556
test: discard unused results
JohelEGP cbd977b
refactor(to_cpp1): avoid the UFCS macro to workaround compiler bugs
JohelEGP 241298e
test: update GCC 13 results
JohelEGP 8764fe4
test: remove Clang 18 results
JohelEGP cc1516a
refactor(sema): avoid pointer arithmetic
JohelEGP d97a328
Merge branch 'main' into last_use
JohelEGP d2d0d3e
test: regenerate results
JohelEGP e3d17e2
refactor(sema): avoid pointer arithmetic
JohelEGP 80f499f
Add regression test result diffs from my machine
hsutter 84edf89
test: comment Clang 12 limitation
JohelEGP 782e078
Merge branch 'main' into last_use
JohelEGP 1b57ea0
test: apply CI patches
JohelEGP 4382aa1
test: apply CI patches
JohelEGP 7cf1093
test: apply CI patches
JohelEGP 870df49
Tweak: Change "final position" to "global token order"
hsutter 3b0f2c2
Minor tweaks
hsutter 87c2344
Merge branch 'main' into last_use
hsutter File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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,74 @@ | ||
f_inout: (inout x: int) -> _ = { | ||
x *= 2; | ||
return x; | ||
} | ||
|
||
issue_350: () = { | ||
x := 21; | ||
|
||
l1 := :(forward x) = { | ||
std::cout << f_inout(forward x) << std::endl; | ||
}; | ||
|
||
l1(x); | ||
|
||
x++; | ||
} | ||
|
||
issue_683: (args) = { | ||
for args do (n) { | ||
_ = n; | ||
} | ||
|
||
n: int; | ||
n = 0; | ||
} | ||
|
||
issue_825: () = { | ||
_ = :(copy b) _ = b; | ||
_ = :(move c) _ = c; | ||
_ = :(forward d) _ = d; | ||
} | ||
|
||
issue_832: () = { | ||
i := 0; | ||
while i { } | ||
} | ||
|
||
f_inout: (inout _: std::unique_ptr<int>) = { } | ||
f_copy: (copy _...) = { } | ||
|
||
issue_857: type = { | ||
a: std::unique_ptr<int>; | ||
b: std::unique_ptr<int>; | ||
operator=: (out this, move that) = { } | ||
operator=: (move this) = f_copy(a, this.b); | ||
f: (move this) = f_copy(this); | ||
f: (move this, move that) = f_copy(this, that); | ||
g: (move this) = f_copy(this.a); | ||
g: (move this, move that) = f_copy(this.a, that.a); | ||
h: (inout this) = f_inout(a); | ||
i: (move this) = f_copy(a); | ||
j: (move this) = f_copy(a); | ||
k: (move this) = f_copy(a, b); | ||
} | ||
|
||
issue_857_2: @struct type = { | ||
a: std::unique_ptr<int>; // OK: No error about 'a' being unused. | ||
} | ||
|
||
gi: int = 0; | ||
issue_857_3: @struct type = { | ||
i: std::add_lvalue_reference_t<int> = gi; | ||
f: (move this) = _ = f_inout(i); | ||
} | ||
|
||
//draw: () = { | ||
// pos := 0; | ||
// vertex := :(_) = { }; | ||
// _ = (pos).vertex(); | ||
//} | ||
|
||
main: (args) = { | ||
issue_683(args); | ||
} |
Empty file.
Empty file.
Empty file.
Empty file.
This file contains hidden or 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 hidden or 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,155 @@ | ||
|
||
#define CPP2_IMPORT_STD Yes | ||
|
||
//=== Cpp2 type declarations ==================================================== | ||
|
||
|
||
#include "cpp2util.h" | ||
|
||
#line 1 "pure2-last-use.cpp2" | ||
|
||
#line 41 "pure2-last-use.cpp2" | ||
class issue_857; | ||
|
||
|
||
#line 56 "pure2-last-use.cpp2" | ||
class issue_857_2; | ||
|
||
|
||
#line 61 "pure2-last-use.cpp2" | ||
class issue_857_3; | ||
|
||
|
||
//=== Cpp2 type definitions and function declarations =========================== | ||
|
||
#line 1 "pure2-last-use.cpp2" | ||
[[nodiscard]] auto f_inout(int& x) -> auto; | ||
|
||
#line 6 "pure2-last-use.cpp2" | ||
auto issue_350() -> void; | ||
|
||
#line 18 "pure2-last-use.cpp2" | ||
auto issue_683(auto const& args) -> void; | ||
|
||
#line 27 "pure2-last-use.cpp2" | ||
auto issue_825() -> void; | ||
|
||
#line 33 "pure2-last-use.cpp2" | ||
auto issue_832() -> void; | ||
|
||
#line 38 "pure2-last-use.cpp2" | ||
auto f_inout([[maybe_unused]] std::unique_ptr<int>& unnamed_param_1) -> void; | ||
auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void; | ||
|
||
class issue_857 { | ||
private: std::unique_ptr<int> a; | ||
private: std::unique_ptr<int> b; | ||
public: issue_857(issue_857&& that) noexcept; | ||
#line 44 "pure2-last-use.cpp2" | ||
public: auto operator=(issue_857&& that) noexcept -> issue_857& ; | ||
public: ~issue_857() noexcept; | ||
public: auto f() && -> void; | ||
public: auto f(issue_857&& that) && -> void; | ||
public: auto g() && -> void; | ||
public: auto g(issue_857&& that) && -> void; | ||
public: auto h() & -> void; | ||
public: auto i() && -> void; | ||
public: auto j() && -> void; | ||
public: auto k() && -> void; | ||
}; | ||
|
||
class issue_857_2 { | ||
public: std::unique_ptr<int> a; // OK: No error about 'a' being unused. | ||
}; | ||
|
||
extern int gi; | ||
class issue_857_3 { | ||
public: std::add_lvalue_reference_t<int> i {gi}; | ||
public: auto f() && -> void; | ||
}; | ||
|
||
//draw: () = { | ||
// pos := 0; | ||
// vertex := :(_) = { }; | ||
// _ = (pos).vertex(); | ||
//} | ||
|
||
auto main(int const argc_, char** argv_) -> int; | ||
|
||
//=== Cpp2 function definitions ================================================= | ||
|
||
#line 1 "pure2-last-use.cpp2" | ||
[[nodiscard]] auto f_inout(int& x) -> auto{ | ||
#line 2 "pure2-last-use.cpp2" | ||
x *= 2; | ||
return x; | ||
} | ||
|
||
auto issue_350() -> void{ | ||
auto x {21}; | ||
|
||
auto l1 {[](auto&& x) mutable -> void{ | ||
std::cout << f_inout(CPP2_FORWARD(x)) << std::endl; | ||
}}; | ||
|
||
std::move(l1)(x); | ||
|
||
++x; | ||
} | ||
|
||
auto issue_683(auto const& args) -> void{ | ||
for ( auto const& n : args ) { | ||
static_cast<void>(n); | ||
} | ||
|
||
cpp2::deferred_init<int> n; | ||
n.construct(0); | ||
} | ||
|
||
auto issue_825() -> void{ | ||
static_cast<void>([](auto b) mutable -> auto { return static_cast<void>(std::move(b)); }); | ||
static_cast<void>([](auto&& c) mutable -> auto { return static_cast<void>(std::move(c)); }); | ||
static_cast<void>([](auto&& d) mutable -> auto { return static_cast<void>(CPP2_FORWARD(d)); }); | ||
} | ||
|
||
auto issue_832() -> void{ | ||
auto i {0}; | ||
while( i ) {} | ||
} | ||
|
||
auto f_inout([[maybe_unused]] std::unique_ptr<int>& unnamed_param_1) -> void{} | ||
auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void{} | ||
|
||
#line 44 "pure2-last-use.cpp2" | ||
issue_857::issue_857(issue_857&& that) noexcept | ||
: a{ std::move(that).a } | ||
, b{ std::move(that).b }{} | ||
#line 44 "pure2-last-use.cpp2" | ||
auto issue_857::operator=(issue_857&& that) noexcept -> issue_857& { | ||
a = std::move(that).a; | ||
b = std::move(that).b; | ||
return *this; } | ||
#line 45 "pure2-last-use.cpp2" | ||
issue_857::~issue_857() noexcept { f_copy(std::move(*this).a, std::move((*this)).b); } | ||
auto issue_857::f() && -> void { f_copy(std::move((*this))); } | ||
auto issue_857::f(issue_857&& that) && -> void { f_copy(std::move((*this)), std::move(that)); } | ||
auto issue_857::g() && -> void { f_copy(std::move((*this)).a); } | ||
auto issue_857::g(issue_857&& that) && -> void { f_copy(std::move((*this)).a, std::move(that).a); } | ||
auto issue_857::h() & -> void { f_inout(a); } | ||
auto issue_857::i() && -> void { f_copy(std::move(*this).a); } | ||
auto issue_857::j() && -> void { f_copy(std::move(*this).a); } | ||
auto issue_857::k() && -> void { f_copy(std::move(*this).a, std::move(*this).b); } | ||
|
||
#line 60 "pure2-last-use.cpp2" | ||
int gi {0}; | ||
|
||
#line 63 "pure2-last-use.cpp2" | ||
auto issue_857_3::f() && -> void { static_cast<void>(f_inout(std::move(*this).i)); } | ||
|
||
#line 72 "pure2-last-use.cpp2" | ||
auto main(int const argc_, char** argv_) -> int{ | ||
auto const args = cpp2::make_args(argc_, argv_); | ||
#line 73 "pure2-last-use.cpp2" | ||
issue_683(args); | ||
} | ||
|
This file contains hidden or 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,2 @@ | ||
pure2-last-use.cpp2... ok (all Cpp2, passes safety checks) | ||
|
This file contains hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.