SYCL test/abi coverage map¶
This page maps the upstream Intel DPC++ / intel/llvm ABI test suite at
sycl/test/abi/ onto
abicheck's detectors, and records which scenarios abicheck catches, by what
mechanism, and at what evidence tier.
The two suites are complementary in form:
- Upstream uses single-build golden checks — it compiles the SYCL headers,
dumps record layouts (
-fdump-record-layouts), vtable layouts, or the exported-symbol list, andFileChecks the result against a checked-in expectation. - abicheck does a two-snapshot diff — it compares an old and a new build of the library and reports what changed.
They overlap on which regressions they catch, not on how. Where upstream catches "this layout is wrong vs. the golden", abicheck catches "this layout changed vs. the previous release".
Coverage matrix¶
| Upstream test | What it guards | abicheck mechanism | Catches a regression? | Min tier |
|---|---|---|---|---|
sycl_symbols_linux.dump, sycl_symbols_windows.dump |
Exact exported-symbol set (ELF + PE) | Exported-symbol add/remove diff (diff_symbols, diff_platform) |
✅ Yes | L0 |
layout_accessors_device.cpp, layout_accessors_host.cpp |
Accessor record layout (offsets, sizeof, align) |
type_size_changed / struct_field_offset_changed / struct_alignment_changed (DWARF or headers) |
✅ Yes | L1 |
layout_array.cpp, layout_buffer.cpp, layout_image.cpp, layout_span.cpp, layout_vec.cpp, layout_nd_range_view.cpp, layout_property_holder.cpp, layout_compile_time_kernel_info.cpp, layout_host_kernel_ref.cpp, layout_tls_code_loc_t.cpp |
Record layout of the named class | type_size_changed, struct_field_offset_changed, base_class_offset_changed, tail_padding_reuse_changed |
✅ Yes | L1 |
layout_handler.cpp |
sycl::handler layout (sizeof=176, member offsets) |
same layout-diff kinds | ✅ Yes | L1 |
layout_exception.cpp |
sycl::exception layout (polymorphic) |
layout-diff plus vtable_slot_count_changed / rtti_inheritance_changed at L0 |
✅ Yes | L0 (vtable/RTTI) / L1 (fields) |
vtable.cpp |
Virtual-table layout | type_vtable_changed (DWARF) and vtable_slot_count_changed (L0, from _ZTV size) |
✅ Yes | L0 |
symbol_size_alignment.cpp |
sizeof/alignof of public types |
type_size_changed, type_alignment_changed, symbol_size_changed |
✅ Yes | L0/L1 |
preview_lib_marker.cpp |
Presence of the preview-ABI marker symbol | Symbol presence/absence diff | ⚠️ Indirect (as a symbol add/remove, not understood as a preview marker) | L0 |
abi_crossing_type_traits.cpp |
Type-trait values across the ABI boundary | Only insofar as it manifests as a layout/symbol change | ⚠️ Partial | L1 |
sycl_abi_neutrality_test.cpp, sycl_classes_abi_neutral_test.cpp |
Rule: no SYCL class may embed std::string/std::list by value (dual-ABI hazard) |
public_api_exposes_stl_by_value (RISK) flags STL-by-value; a new embed also shows as type_size_changed. No single-build "neutrality rule" lint. |
⚠️ Partial — see gap below | L1/L2 |
Worked example: PR #20821¶
The shared_ptr<device_impl> → raw-pointer change in
intel/llvm#20821 is captured as
example case126_sycl_device_impl_ptr.
abicheck reports it as type_size_changed sycl::device (16 → 8 bytes) — the
root cause. Note that upstream's sycl_symbols_*.dump guard could not see
this directly (no mangled name changed), which is why it only caught the
downstream Windows symbol churn and needed follow-up PRs (#20902, #21028).
What abicheck recovers without DWARF (L0, symbols only)¶
A common worry is that a stripped release with no debug info and no headers
defeats layout analysis. It does not defeat all of it: the Itanium C++ ABI
encodes several layout facts in the sizes of the objects it emits into
.dynsym, which abicheck decodes in diff_elf_layout.py:
| Signal | Source | What it reveals | Kind |
|---|---|---|---|
| Exported-symbol set | .dynsym names |
Added/removed/renamed functions & objects (the .dump-equivalent) |
func_removed, func_removed_elf_only, … |
| Object symbol size | st_size of data symbols |
sizeof of exported global objects |
symbol_size_changed |
| Vtable slot count | st_size of _ZTV<class> (slots ≈ size/ptr − 2) |
A virtual method was added/removed/reordered | vtable_slot_count_changed |
| Inheritance shape | st_size of _ZTI<class> (2 words = no base, 3 = single base, ≥4 = multiple/virtual) |
Base-class set changed | rtti_inheritance_changed |
| Mangled-name signature | demangled .dynsym entries |
Parameter/return types & the owning class of each method | feeds the symbol diff |
The vtable and RTTI signals are the important addition: a virtual-method change
or a base-class change need not rename any mangled symbol, yet it resizes
the class's _ZTV/_ZTI object — so abicheck sees it even on a fully stripped
library. This is the binary-only analogue of upstream's vtable.cpp and the
inheritance half of the layout_* goldens.
What still needs DWARF, headers, or a golden: exact member offsets and the
sizeof of a type that is not backed by a sized data symbol (e.g. a class only
ever passed by pointer). At L0 those fall back to layout_unverifiable (RISK,
non-escalating) rather than a false "compatible".
Known gaps¶
- ABI-neutrality rule lint.
sycl_classes_abi_neutral_test.cppasserts an invariant on a single build ("no SYCL class embedsstd::string/std::list"). abicheck only diffs two builds, so it flags a newly introduced embed (as a layout change /public_api_exposes_stl_by_value) but has no standalone "this one build violates the neutrality rule" lint. Tracked as a possible single-snapshot lint lane. - Golden layouts for named classes. abicheck catches a regression from the previous release, not a layout that is wrong on first introduction. A curated golden-layout fixture for the named SYCL classes would close that.
- Preview-marker semantics.
preview_lib_marker.cppis understood only as a generic symbol presence/absence, not as a preview-ABI toggle.