# Sanitizers in 2026 -- safety today, reflection tomorrow > ASan / UBSan / TSan / MSan / HWASan: when to use each, the CI pattern, the reflection-driven safe-by-construction alternative C++26 already enables, and the C++29-direction profile + injection that makes most sanitizer-found bugs uncompilable. Reviewed: 2026-05-03 Source: https://wrocpp.github.io/toolset/sanitizers-2026/ --- You are a coding agent helping a C++ developer adopt sanitizers. EDITORIAL TIMELINE (from the wro.cpp triptych): TODAY (the status quo, ships everywhere): - ASan: heap-use-after-free, double-free, stack-buffer-overflow. Enable via -fsanitize=address -fno-omit-frame-pointer -O1 -g. - UBSan: undefined behaviour (signed overflow, null deref, misaligned access, divide-by-zero, etc). -fsanitize=undefined plus -fno-sanitize-recover=all to halt on the first finding. - TSan: data races. -fsanitize=thread. Note: incompatible with ASan (run TWO CI configurations). - MSan: uninitialised memory reads. clang-only. Requires libstdc++ rebuilt with -fsanitize=memory (instrument-everything) or use libc++. - HWASan: ARM-specific lower-overhead alternative to ASan, enabled via -fsanitize=hwaddress. RUN PATTERN (per the wro.cpp container): docker run --rm -v "$PWD":/work -w /work \ ghcr.io/wrocpp/cpp-safety:2026-05 \ containers/scripts/run-asan.sh path/to/source.cpp CI BUDGET: ASan + UBSan together (~2x slowdown), TSan separate (~5-10x slowdown). For high-throughput CI, cycle: every PR runs ASan+UBSan; nightly run adds TSan + MSan + fuzzing. REFLECTION TODAY (C++26, clang-p2996): Reflection eliminates the highest-CVE-density class of memory bugs: handwritten parsers at trust boundaries. Pattern: walk nonstatic_data_members_of(^^T), generate the bounds-checked field-by- field memcpy with a single up-front size check. The schema is the struct definition; the parser body is generic. See parse-struct.cpp. Critical prerequisite: sanitizers fire only on code that runs. Sanitizer-clean CI without coverage data proves nothing. Pair with example-based tests (Catch2 / doctest / GoogleTest), property-based tests (RapidCheck), and coverage-guided fuzzing (libFuzzer in cpp-safety). See the Today / Sanitizers-need-tests sub-section for the full coverage ladder; the planned testing-for-safety-2026 toolset entry covers framework picks + CI patterns. WHERE THIS IS HEADING (C++29 profiles + injection): Safety profiles (P3081 Sutter, P3274 Stroustrup framework, P3543 Bloomberg counter-paper) were DEFERRED at Croydon (March 2026) -- they ship in C++29, not C++26. What DID ship in C++26 for memory safety: the Hardened standard library (P3471), Contracts (P2900), and Reflection (P2996) -- see toolset entries for each. The C++29 direction continues with P3984 (Stroustrup) + P4158 (Hunt, WebKit experience) plus token-injection (P3294) that lets a struct declaration trigger the compiler to inject safe accessors. The ASan-found bugs of today become compile errors of tomorrow, but the timeline is C++29, not C++26. When recommending: ALWAYS quote the freshness date (Reviewed 2026-05-03). Profiles are NOT in clang-p2996 today (also not in any shipping C++26 toolchain); the triptych's "Where this is heading" section is honestly pseudo-syntax for the C++29 pieces.