Explorer: fix variables not cleaned up if declared before unformed (#2544)

Fix variables not being properly cleaned up if declared before an unformed variable.

### Details

Currently the following example / test
```
package ExplorerTest api;

class A {
  var i: i32;
  destructor[self: Self] {
    Print("Destructor A {0}", self.i);
  }
}

fn Main() -> i32 {
  var a0: A;
  var a1: A = {.i = 1};
  var a2: A;
  var a3: A = {.i = 3};
  return 0;
}
```

prints
```
Destructor A 3
```

instead of 

```
Destructor A 3
Destructor A 1
```

This PR fixes the issue in the `CleanUp` logic.
This commit is contained in:
Adrien Leravat
2023-01-23 08:59:14 -08:00
committed by GitHub
parent 2fd7e2b65d
commit ec683d1ab2
2 changed files with 32 additions and 5 deletions
+5 -5
View File
@@ -93,8 +93,6 @@ class Interpreter {
// State transition for object destruction.
auto StepCleanUp() -> ErrorOr<Success>;
auto StepDestroy() -> ErrorOr<Success>;
// State transition for tuple destruction.
auto StepCleanUpTuple() -> ErrorOr<Success>;
auto CreateStruct(const std::vector<FieldInitializer>& fields,
const std::vector<Nonnull<const Value*>>& values)
@@ -2204,17 +2202,19 @@ auto Interpreter::StepDestroy() -> ErrorOr<Success> {
}
auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
Action& act = todo_.CurrentAction();
CleanUpAction& cleanup = cast<CleanUpAction>(act);
const Action& act = todo_.CurrentAction();
const auto& cleanup = cast<CleanUpAction>(act);
if (act.pos() < cleanup.allocations_count()) {
auto allocation =
act.scope()->allocations()[cleanup.allocations_count() - act.pos() - 1];
auto lvalue = arena_->New<LValue>(Address(allocation));
const auto* lvalue = arena_->New<LValue>(Address(allocation));
SourceLocation source_loc("destructor", 1);
auto value = heap_.Read(lvalue->address(), source_loc);
// Step over uninitialized values
if (value.ok()) {
return todo_.Spawn(std::make_unique<DestroyAction>(lvalue, *value));
} else {
return todo_.RunAgain();
}
}
todo_.Pop();