Skip to content
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

"this" not protected in lambdas in tail-recursive functions #4684

Closed
RustanLeino opened this issue Oct 19, 2023 · 0 comments · Fixed by #5474
Closed

"this" not protected in lambdas in tail-recursive functions #4684

RustanLeino opened this issue Oct 19, 2023 · 0 comments · Fixed by #5474
Assignees
Labels
during 4: bad execution of correct program A bug in the Dafny compiler that causes a correct Dafny program to execute incorrectly kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: code-generation Support for transpiling Dafny to another language. If relevant, add a `lang:` tag priority: next Will consider working on this after in progress work is done

Comments

@RustanLeino
Copy link
Collaborator

Dafny version

4.3.0

Code to produce this issue

class C {
  var data: nat
  var next: C?

  constructor (n: nat) {
    data := n;
    if n == 0 {
      next := null;
    } else {
      next := new C(n - 1);
    }
  }

  function FWithoutTailRecursion(n: nat, g: () ~> int): int
    requires g.requires()
    reads *
  {
    if n == 0 || next == null then
      g()
    else
      var h := () reads this => this.data;
      var r := next.FWithoutTailRecursion(n - 1, if n < 20 then g else h);
      r
  }

  function F(n: nat, g: () ~> int): int
    requires g.requires()
    reads *
  {
    if n == 0 || next == null then
      g()
    else
      var h := () reads this => this.data;
      next.F(n - 1, if n < 20 then g else h)
  }
}

method Main() {
  var c := new C(25);
  print c.FWithoutTailRecursion(25, () => -1), "\n"; // 20
  print c.F(25, () => -1), "\n"; // 20
}

Command to run and resulting output

% dafny run test.dfy

Dafny program verifier finished with 4 verified, 0 errors
20
0

What happened?

Both the non-tail-recursive function and the tail-recursive one should output 20. However, the tail-recursive one outputs 0. This is a problem for the C#, JavaScript, Go, and Python backends. The Java backend emits malformed code.

The problem is that, for tail recursive instance function, this (which the target languages generally don't allow to be modified) is placed in a local variable, _this. This variable needs to be protected when inLetExprBody is true, just like in the IdentifierExpr case.

What type of operating system are you experiencing the problem on?

Mac

@RustanLeino RustanLeino added kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label during 4: bad execution of correct program A bug in the Dafny compiler that causes a correct Dafny program to execute incorrectly labels Oct 19, 2023
@keyboardDrummer keyboardDrummer added the priority: next Will consider working on this after in progress work is done label Feb 21, 2024
@keyboardDrummer keyboardDrummer added the part: code-generation Support for transpiling Dafny to another language. If relevant, add a `lang:` tag label Apr 29, 2024
@fabiomadge fabiomadge self-assigned this May 13, 2024
fabiomadge added a commit to fabiomadge/dafny that referenced this issue May 21, 2024
fabiomadge added a commit that referenced this issue May 24, 2024
…unction or method (#5474)

Fixes #4684

---------

Co-authored-by: Aaron Tomb <[email protected]>
atomb added a commit to atomb/dafny that referenced this issue May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
during 4: bad execution of correct program A bug in the Dafny compiler that causes a correct Dafny program to execute incorrectly kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: code-generation Support for transpiling Dafny to another language. If relevant, add a `lang:` tag priority: next Will consider working on this after in progress work is done
Projects
None yet
3 participants