Skip to content

Emit vtables/type infos with weak ODR linkage for MachO compatibility#1206

Merged
marcauberer merged 1 commit into
mainfrom
fix/vtable-odr
Jun 14, 2026
Merged

Emit vtables/type infos with weak ODR linkage for MachO compatibility#1206
marcauberer merged 1 commit into
mainfrom
fix/vtable-odr

Conversation

@marcauberer

Copy link
Copy Markdown
Member

Problem

Since the bootstrap accept()-dispatch commits, macOS CI fails to link BootstrapCompilerTests.bootstrapCompiler_unitWrapperAstVisualizer:

duplicate symbol 'vtable for IAbstractAstVisitor' in:
    .../abstract-ast-visitor-intf.o
    .../abstract-ast-visitor.o
ld: 3 duplicate symbols

IAbstractAstVisitor is deliberately declared in two files — an empty forward declaration in abstract-ast-visitor-intf.spice (so ast-nodes.spice can type accept(IAbstractAstVisitor*) without a circular import) and the full typed interface in abstract-ast-visitor.spice. Both translation units emit the vtable/typeinfo/typeinfo name symbols.

These were emitted as strong ExternalLinkage symbols relying on a comdat group to coalesce the duplicates. attachComdatToSymbol skips comdat on MachO (macOS has no comdat support), so on macOS the two strong definitions collide. On ELF the comdat coalesces them, which is why Linux CI was green.

Fix

VTables, type infos and type info names are ODR entities that can legitimately appear in multiple translation units. Emit them with WeakODRLinkage instead of strong external, exactly as Clang emits C++ vtables/type infos:

  • ELF: pairs with the existing comdat group — behavior unchanged, still coalesced.
  • MachO: the weak/coalesced linkage lets the linker merge the duplicates instead of erroring.

Regular functions and global variables are unaffected (they still use getSymbolLinkageType).

Tests

  • The previously-failing bootstrapCompiler_unitWrapperAstVisualizer and the interface/bootstrap-linker tests pass (22/22).
  • Full IRGeneratorTests suite passes (171/171).
  • Only two reference IR files changed (success-cross-sourcefile-interfaces), regenerated via --update-refs; the only delta is the weak_odr prefix on the public vtable/type info, matching standard Clang codegen.

🤖 Generated with Claude Code

VTables, type infos and type info names are ODR entities that may
legitimately be emitted in more than one translation unit (e.g. an
interface that is forward-declared in one file and fully defined in
another, as the bootstrap IAbstractAstVisitor is). They were emitted as
strong ExternalLinkage symbols relying on a comdat group to coalesce
duplicates. comdat is skipped on MachO, so on macOS the duplicate
definitions collided with a linker "duplicate symbol" error.

Give these symbols weak ODR linkage, matching how Clang emits C++
vtables/type infos. On ELF this pairs with the existing comdat group
(behavior unchanged); on MachO the weak/coalesced linkage lets the
linker merge the duplicates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@marcauberer marcauberer requested a review from a team as a code owner June 14, 2026 22:24
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions github-actions Bot added tests Contains changes to the test cases compiler labels Jun 14, 2026
@marcauberer marcauberer enabled auto-merge (squash) June 14, 2026 22:25
@marcauberer marcauberer merged commit d4ae7f2 into main Jun 14, 2026
8 checks passed
@marcauberer marcauberer deleted the fix/vtable-odr branch June 14, 2026 22:38
@marcauberer marcauberer added this to the 0.27.0 milestone Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler size/S tests Contains changes to the test cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant