case218 — a GLOBAL export loss stays BREAKING under a binding: weak rule¶
| Field | Value |
|---|---|
| Verdict | 🔴 BREAKING |
| Category | Breaking |
| Classification | Rule |
| Platforms | Linux |
| Flags | ABI break |
Detected ChangeKinds |
func_removed_elf_only |
| Source files | catalog/cases/case218_export_loss_strong_binding_stays_breaking/ |
| Rule family | export-loss-strong-binding-stays-breaking |
| Subject | ELF export and linker metadata |
Verdict and consumer impact¶
This is the sibling of case217_export_loss_weak_binding_demoted. It uses the
same policy.yaml and the same three WEAK losses, and NEW also drops
ns::strong_fn, a GLOBAL export declared in the public header. A consumer that
calls strong_fn fails to link or bind against NEW, so this is a real break.
The binding: weak rule matches only WEAK findings. The strong_fn finding
carries symbol_binding: "global", so the rule does not match it and the run
stays BREAKING, exit code 4. The WEAK losses are still demoted to a risk;
the verdict is set by the strong removal alone.
Old/new diff¶
| v1 (OLD) | v2 (NEW) | |
|---|---|---|
hdr_inline() |
called from Pub::g(), emitted WEAK |
not emitted (as in case217) |
weak_undeclared() |
__attribute__((weak)), not in any header |
not defined |
detail::P<float> ctor |
instantiated by Pub::q() |
not instantiated |
strong_fn() |
GLOBAL, declared and defined | declared in v2.h, not defined |
abicheck command¶
abicheck dump libv1.so -H v1.h -o v1.json
abicheck dump libv2.so -H v2.h -o v2.json
rm libv1.so
abicheck compare v1.json v2.json --policy policy.yaml
Expected abicheck finding¶
- Verdict:
BREAKING, exit code4. - The WEAK findings (
func_visibility_changedonhdr_inline,func_removed_elf_onlyonweak_undeclaredand theP<float>constructor) carrysymbol_binding: "weak"and are reclassified torisk. func_visibility_changedonstrong_fncarriessymbol_binding: "global"and is not reclassified, so it keeps the run atBREAKING.
Minimum evidence¶
min_evidence: L2 (public headers), as in case217.
Why abicheck catches it¶
Same mechanism as case217: the ELF .dynsym gives each finding its old-side
binding, and the binding: selector compares that value
(policy/selectors.py). Because the selector compares the value, a GLOBAL
finding is never matched by a rule written for WEAK ones.
Source files¶
policy.yamlv1.cppv1.hv2.cppv2.h
See also: Compatibility Catalog · All BREAKING cases · Category: Breaking · Rule: Strong export loss stays breaking under a binding rule · Subject: ELF export and linker metadata.