Skip to content

fix module-scope variables defaulting to double instead of actual type#48

Merged
cs01 merged 1 commit intomainfrom
fix/module-scope-types
Feb 23, 2026
Merged

fix module-scope variables defaulting to double instead of actual type#48
cs01 merged 1 commit intomainfrom
fix/module-scope-types

Conversation

@cs01
Copy link
Copy Markdown
Owner

@cs01 cs01 commented Feb 23, 2026

Summary

Fix module-scope variables defaulting to double instead of their actual type, causing LLVM opt crashes.

Problem

Top-level variable declarations like const parts = "hello".match(/re/) crashed during LLVM optimization with type mismatches:

'%1' defined with type 'ptr' but expected 'double'

The same code worked fine when wrapped in a function.

Root cause

Module-scope variables go through a two-phase process:

  1. generateGlobalVariableDeclarations() emits @name = global <type> <default>
  2. allocate() in @main stores the expression result into the pre-declared global

Phase 1 has an incomplete type classifier (~12 cases) compared to the function-local path which handles 25 cases via classifyVariable(). When it couldn't determine the type, it fell back to double — so .match(), .split(), function calls returning strings, etc. all became @name = global double 0.0. Phase 2 then tried to store i8* %expr, double* @name, causing the type mismatch.

Additionally, struct-value globals (%StringArray, %Array, %Map, %Set) were declared as by-value structs with zeroinitializer, while the function-local path correctly uses pointer types — another source of mismatches.

Fix

  • Convert all struct-value global types to pointer types matching the local path (%StringArray -> %StringArray*, %Array -> %Array*, %Map -> %Map*, etc.)
  • Extend the global store path to bitcast when the expression's actual type doesn't match the global's declared pointer type
  • Remove the now-unnecessary struct-value load+store branch
  • Replace the silent double fallback with a compile error for unclassified expression types — instead of silently guessing the wrong type and crashing later in opt, the compiler now tells you: cannot determine type of module-scope variable 'x'. Move the declaration inside a function, or add a type annotation
  • Number literals (const x = 42) still correctly default to double

Test plan

  • Added 3 test fixtures in tests/fixtures/globals/ (module-scope .match(), .split(), function return)
  • All 355 tests pass (native compiler)
  • All 222 tests pass (Node.js compiler)

@cs01 cs01 force-pushed the fix/module-scope-types branch from d96d95f to 6ee4b63 Compare February 23, 2026 21:16
@cs01 cs01 force-pushed the fix/module-scope-types branch from 6ee4b63 to 2b4ee91 Compare February 23, 2026 21:21
@cs01 cs01 merged commit 4c399d3 into main Feb 23, 2026
12 checks passed
@cs01 cs01 deleted the fix/module-scope-types branch February 23, 2026 21:28
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.

1 participant