Skip to content

codegen: generated clone-symbol suffixes (__generic/__typed_*/__spec_*/__pshape) collide with user members of the same name #6927

Description

@proggeramlug

Summary

Perry's specialized/clone symbol naming composes LLVM symbol names by appending a fixed suffix to a user method or function name. A user-declared member whose name already ends in one of those suffixes collides with a generated clone symbol, producing two definitions of the same LLVM symbol.

Repro shape

class C {
  foo(): number { return 1 }
  foo__generic(): number { return 2 }   // collides with the clone of `foo`
}

sanitize_member passes plain [A-Za-z0-9_] names through unchanged, so no escaping prevents the collision.

Scope — the whole suffix family

At least eight generated suffixes share this hazard:

__generic · __typed_f64 · __typed_i32 · __typed_i1 · __typed_string · __typed_f64_recv · __spec_<repmangle> · __pshape (proposed in #6925)

foo + foo__generic already collides on main today, so this is pre-existing and family-wide, not introduced by any single PR.

Severity: low urgency, but should not stay unowned

It fails loudly — duplicate definitions are rejected by the LLVM IR verifier, i.e. a hard compile error, not a miscompile. No program silently takes a wrong path. But the failure mode is inscrutable for a user who simply named a method foo__generic, and the surface grows with every new clone kind.

Suggested fix directions

  1. Cheap, local (per-PR mitigation): before emitting a clone, refuse if the composed name is already a registered method/function symbol; stand down to the ordinary guarded lowering (always correct, just slower). perf(codegen): repsel Phase 5a — Ptr<Shape> proven this in methods #6925 plans this for __pshape only.
  2. General: make the suffix namespace unforgeable — e.g. reserve a character that sanitize_member escapes out of user identifiers (so a user name can never produce the reserved sequence), or hash-suffix clone symbols the way monomorph/mangle.rs content-addresses specializations, or thread a per-module uniquifier the way func_registry.rs's __dupN disambiguation already does for base symbols.

A general fix touches every clone kind plus the Phase 2 __spec_ reachability ratchet (codegen/spec_abi.rs) and native_proof_regressions, which is why it wants its own change rather than riding along in a perf PR.

Provenance

Found by CodeRabbit review on #6925 (representation-selection Phase 5a); assessed there as real, pre-existing, and family-wide.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions