Skip to content

fix: prevent infinite loop when modifies clause references non-composite type (#490)#731

Merged
MikaelMayer merged 16 commits intomainfrom
issue-490-laurelanalyze-infinite-loop-when-procedu
Apr 3, 2026
Merged

fix: prevent infinite loop when modifies clause references non-composite type (#490)#731
MikaelMayer merged 16 commits intomainfrom
issue-490-laurelanalyze-infinite-loop-when-procedu

Conversation

@MikaelMayer
Copy link
Copy Markdown
Contributor

@MikaelMayer MikaelMayer commented Apr 1, 2026

Problem

strata laurelAnalyze enters an infinite loop (emitting PANIC messages and consuming unbounded memory) when a Laurel program contains a procedure with a modifies clause referencing a non-composite type, such as a parameter of type int.

The root cause is that the heap parameterization pass treats any procedure with a non-empty modifies list as heap-modifying, regardless of the types in the list. When the modifies list contains a non-composite type, the modifies clause transformation generates invalid frame conditions, leading to downstream failures.

Fix

  1. Single source of truth: ModifiesTypeKind enum and classifyModifiesHighType in LaurelTypes.lean serve as the canonical type classification for modifies clauses. Both isHeapRelevantType and classifyModifiesType delegate to it.

  2. Separation of concerns: Non-composite modifies filtering and diagnostics live in ModifiesClauses.lean (filterNonCompositeModifies), keeping the heap parameterization phase agnostic to modifies clauses. The filtering runs as a pre-pass before heap parameterization in the pipeline.

  3. Error reporting: Non-composite modifies entries produce a diagnostic error (e.g. modifies clause entry has non-composite type 'int' and will be ignored) instead of being silently filtered.

Testing

All existing tests pass. Added a regression test (T8_NonCompositeModifies) that verifies procedures with non-composite modifies entries terminate and produce the expected diagnostic errors.

Fixes #490

…490)

When a procedure has a modifies clause referencing a non-composite type
(e.g., a global variable of type int), the heap parameterization pass
incorrectly treated the procedure as heap-modifying, and the modifies
clause transformation generated invalid frame conditions comparing
Composite objects to primitive types.

Fix by filtering out non-composite modifies entries in two places:
- HeapParameterization: filter before heap analysis so non-composite
  modifies entries don't trigger heap parameterization
- ModifiesClauses: filter in extractModifiesEntries so only Composite
  and Set types generate frame conditions
MikaelMayer

This comment was marked as resolved.

@MikaelMayer MikaelMayer marked this pull request as ready for review April 1, 2026 20:56
@MikaelMayer MikaelMayer requested a review from a team April 1, 2026 20:56
Comment thread Strata/Languages/Laurel/HeapParameterization.lean Outdated
@MikaelMayer MikaelMayer enabled auto-merge April 2, 2026 15:01
tautschnig

This comment was marked as resolved.

@MikaelMayer

This comment was marked as resolved.

…lication, add regression test

- HeapParameterization now emits diagnostic errors for non-composite modifies
  entries instead of silently filtering them
- Introduced classifyModifiesType in ModifiesClauses to eliminate duplication
  between isHeapRelevantType and extractModifiesEntries
- Added T8_NonCompositeModifies regression test for issue #490
Comment thread Strata/Languages/Laurel/ModifiesClauses.lean
@MikaelMayer

This comment was marked as resolved.

Comment thread Strata/Languages/Laurel/LaurelTypes.lean
Comment thread Strata/Languages/Laurel/HeapParameterization.lean Outdated
Comment thread Strata/Languages/Laurel/HeapParameterization.lean Outdated
Comment thread Strata/Languages/Laurel/HeapParameterization.lean Outdated
…difiesClauses

Address review feedback: keep HeapParameterization agnostic to modifies
clauses by moving the non-composite modifies filtering and diagnostics
into a new filterNonCompositeModifies function in ModifiesClauses.lean.
This function runs before heap parameterization in the pipeline.
@MikaelMayer MikaelMayer added this pull request to the merge queue Apr 3, 2026
Merged via the queue into main with commit ece23d6 Apr 3, 2026
15 checks passed
@MikaelMayer MikaelMayer deleted the issue-490-laurelanalyze-infinite-loop-when-procedu branch April 3, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

laurelAnalyze: infinite loop when procedure has modifies clause referencing a global variable

4 participants