GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Soundness: a state change made through an alias is not seen through the original variable · Issue #337 · liquid-java/liquidjava

Soundness: a state change made through an alias is not seen through the original variable #337

New issue
Copy link
New issue
Copy link
Open
#393
Open
Soundness: a state change made through an alias is not seen through the original variable#337
#393
Copy link
Labels
bugSomething isn't workingSomething isn't working

Description

@CatarinaGamboa
CatarinaGamboa
opened on Oct 6, 2026
Issue body actions

Impact: a real bug passes verification (false negative). It blocks 2 of the 48 real-code examples we built (bugs mined from open-source Java).

Description

After Res b = a;, closing b leaves a in the open state, so a.read() on the closed object passes. Without the alias it is reported (control).

Minimal reproducer

import liquidjava.specification.StateRefinement;
import liquidjava.specification.StateSet;

@StateSet({"open", "closed"})
class Res implements AutoCloseable {
    @StateRefinement(to = "open(this)")
    public Res() {}

    @StateRefinement(from = "open(this)")
    public void read() {}

    @StateRefinement(from = "open(this)", to = "closed(this)")
    public void close() {}
}

public class Repro {
    static void m() {
        Res a = new Res();
        Res b = a;
        b.close();
        a.read();           // a and b are the same object, now closed
    }
}

Expected

Either aliases share one state (a state error at a.read()), or an aliased object's state becomes unknown and the call is rejected as unprovable; not silently accepted.

Actual

Correct! Passed Verification.

Control: the same code without the problem construct is reported

import liquidjava.specification.StateRefinement;
import liquidjava.specification.StateSet;

@StateSet({"open", "closed"})
class Res implements AutoCloseable {
    @StateRefinement(to = "open(this)")
    public Res() {}

    @StateRefinement(from = "open(this)")
    public void read() {}

    @StateRefinement(from = "open(this)", to = "closed(this)")
    public void close() {}
}

public class Control {
    static void m() {
        Res a = new Res();
        a.close();
        a.read();           // without the alias: reported
    }
}
State Refinement Error: found closed(a⁸) but expected open(a⁸)
18 |         Res a = new Res();
19 |         a.close();
20 |         a.read();           // without the alias: reported
   |         ^^^^^^^^^
21 |     }

Reproduced on main at 0472025 (liquidjava-verifier 0.0.35); also on fbfb4e2 and 0.0.33 in the original form.

Context

Found while turning bugs mined from real open-source Java (fixed upstream or still present) into study examples for the error-message study.

Activity

  1. CatarinaGamboa
    added
    bugSomething isn't workingSomething isn't working
    on Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.