Requirements Validation Test Cases¶
This document provides concrete test scenarios for validating that an ABI implementation satisfies the requirements. These tests are implementation-agnostic and should work regardless of which approach (descriptor table, runtime-constructed, or other) is adopted.
Critical Requirements Tests¶
Test: ABI Stability - Forward Compatibility¶
Scenario: A compiler emits contract violations with fields that the runtime library doesn’t recognize.
- Setup:
Compiler: Implements contract ABI version N+1 with new field X
Runtime: Implements contract ABI version N without knowledge of field X
Compilation: Object file contains contracts with field X populated
- Expected behavior:
Runtime successfully constructs
std::contract_violationobjectRuntime uses fields it recognizes from version N
Runtime ignores field X without error
Contract handler receives valid violation object with recognized fields
- Success criteria:
No runtime errors or crashes
Handler receives contract information for all version-N fields
Missing field X does not prevent handler invocation
Test: ABI Stability - Backward Compatibility¶
Scenario: A runtime library expects fields that older object files don’t provide.
- Setup:
Compiler: Implements contract ABI version N
Runtime: Implements contract ABI version N+1, expects new field Y
Compilation: Object file contains contracts without field Y
- Expected behavior:
Runtime detects missing field Y
Runtime uses appropriate default/null value for field Y
Runtime constructs valid
std::contract_violationobjectContract handler receives violation object with defaults for missing fields
- Success criteria:
No runtime errors or crashes
Handler receives contract information for all available fields
Missing field Y has sensible default (empty string, null pointer, etc.)
Test: Cross-Compiler Interoperability¶
Scenario: Object files compiled by different compilers are linked together and execute contract violations.
- Setup:
C++ module or translation unit A: Compiled by compiler X with its contract implementation
C++ module or translation unit B: Compiled by compiler Y with its contract implementation
Linked: Both C++ modules/translation units linked into single executable
Runtime: Single shared standard library
- Expected behavior:
Contract violations in C++ module/translation unit A construct proper
std::contract_violationobjectsContract violations in C++ module/translation unit B construct proper
std::contract_violationobjectsBoth C++ modules/translation units call the same handler with valid violation objects
Handler receives equivalent information regardless of which compiler produced the violation
- Success criteria:
Both compilers emit compatible calling conventions
Standard library correctly interprets data from both compilers
No linker errors due to symbol conflicts
Handler sees consistent field values regardless of source compiler
Test: Efficient Field Omission¶
Scenario: User compiles with flags that omit specific contract data fields.
- Setup:
Compilation flag: Disable source location information
Code: 1000 contracts throughout codebase
Measurement: Compare object file sizes and runtime behavior
- Expected behavior:
Object files contain no storage for omitted source location data
No initialization code generated for omitted fields
Contract violations still work correctly with remaining fields
Handler receives null/empty values for omitted fields
- Success criteria:
Object file size reduction proportional to omitted data
Zero overhead for omitted fields (no vestigial code or data)
No version explosion (single implementation handles omission)
Runtime correctly identifies omitted fields vs. present-but-empty fields
Test: Constructor Isolation¶
Scenario: Contract violation occurs with fields requiring standard library type construction.
- Setup:
Contract: Uses
std::source_locationorstd::string_viewin violation dataUser code: No contract-related includes (compiler-only syntax)
Violation: Trigger contract failure at runtime
- Expected behavior:
No user-provided constructors are invoked
Standard library constructors for
std::source_location,std::string_viewmay be invoked by runtimeViolation object constructed successfully
Handler receives properly initialized violation object
- Success criteria:
No user code executed between violation detection and handler call
Standard library types properly constructed with correct values
Compiler doesn’t need to
#includestandard library headers at contract siteImplementation handles inline namespaces correctly
Test: Minimal Code Generation Impact¶
Scenario: Large codebase adopts contracts and measures compilation impact.
- Setup:
Baseline: Existing codebase at linker size limits
Change: Add contracts (preconditions, postconditions, assertions)
Measurement: Object file size, compilation time, runtime performance
- Expected behavior:
Per-contract code generation is minimal (ideally single function call)
Contract failure code doesn’t inhibit inlining of hot path
Cold path (contract failure) isolated from hot path (normal execution)
Object file growth scales reasonably with number of contracts
- Success criteria:
Per-contract overhead < 50 bytes in .text section
No inlining budget exhaustion in hot functions
Contract failure code in separate section or marked cold
Total object file growth remains manageable for projects at limits
Test: Vendor Extensions Without Coordination¶
Scenario: Two compiler vendors independently add proprietary extensions.
- Setup:
Vendor A: Adds stack trace field to contract violations
Vendor B: Adds performance counter field to contract violations
No coordination: Vendors develop features independently
Deployment: Code compiled by vendor A runs with vendor B’s runtime (and vice versa)
- Expected behavior:
Vendor A’s extension works with vendor A’s runtime
Vendor B’s extension works with vendor B’s runtime
Vendor A’s object files work with vendor B’s runtime (extension ignored)
Vendor B’s object files work with vendor A’s runtime (extension ignored)
- Success criteria:
No namespace conflicts between vendor extensions
No coordination required (no central registry for field types)
Each vendor’s extension accessible when both compiler and runtime from same vendor
Cross-vendor compatibility maintained (unrecognized extensions silently ignored)
Important Requirements Tests¶
Test: Small Specification Surface¶
Validation approach: Analyze the specification itself.
- Evaluation criteria:
Count required entrypoint signatures
Count mandated data structure layouts
Count enumeration values that must be standardized
Count coordination points between vendors
- Success criteria:
Single primary entrypoint function
Minimal required data structure formats
Small set of standardized enumeration values
Vendor extensions possible without central coordination
Test: Deployment Flexibility¶
Scenario: Platform updates high-level standard library without updating low-level ABI library.
- Setup:
Compiler: Updated to support C++26 contracts
High-level library: Updated (libc++/libstdc++)
Low-level ABI library: Not updated (libc++abi/libsupc++)
Deployment: System has old ABI library, new compiler and high-level library
- Expected behavior:
Contracts work if implementation can be provided by high-level library alone
Graceful failure or degraded functionality if low-level library required
- Success criteria:
Implementation strategy clearly documents which library must provide entrypoint
If high-level library sufficient, contracts work without ABI library update
If low-level library required, specification documents this dependency
Note: This test’s importance depends on real-world deployment patterns, which require validation.
Negative Tests¶
Test: Reject User Constructors¶
Scenario: Attempt to use contract violation with fields requiring user-provided constructors.
- Setup:
Code attempts to include user-defined type in violation data
User type has non-trivial constructor
- Expected behavior:
Implementation refuses this configuration
Compiler error or runtime constraint prevents user constructor invocation
- Success criteria:
No arbitrary user code executed during violation processing
Clear distinction between standard library constructors (allowed) and user constructors (forbidden)
Test: Incompatible Standard Versions¶
Scenario: Attempt to link C++26 contracts code with pre-C++26 runtime.
- Setup:
Compiler: C++26 with contracts enabled
Runtime: Pre-C++26 standard library without contract support
- Expected behavior:
Link-time error due to missing entrypoint symbol
Clear error message indicating version mismatch
- Success criteria:
Failure occurs at link time, not runtime
Error message clearly indicates missing contract support
No silent undefined behavior
Version Evolution Tests¶
Test: std::contract_violation Evolution¶
Scenario: The C++ standard adds new fields to std::contract_violation in future standards.
- Setup:
C++26:
std::contract_violationhas fields A, B, CC++29: Standard adds field D to
std::contract_violationMixed deployment: C++26 compiler with C++29 runtime, or vice versa
- Expected behavior:
C++26 code works with C++29 runtime (field D gets default value)
C++29 code works with C++26 runtime (field D ignored by old runtime)
ABI remains compatible across standard versions
- Success criteria:
No recompilation required when standard library updates
Prefix compatibility maintained (existing fields at stable offsets)
New fields addable without breaking old code
Test: Multiple Standards in Single Binary¶
Scenario: Single executable contains object files compiled for different C++ standard versions.
- Setup:
C++ module or translation unit A: Compiled as C++26 with basic contract fields
C++ module or translation unit B: Compiled as C++29 with extended contract fields
C++ module or translation unit C: Compiled as C++32 with additional vendor extensions
Linked: All C++ modules/translation units in single executable with single runtime
- Expected behavior:
All contract violations work correctly
Handler receives appropriate fields for each C++ module/translation unit’s standard version
No conflicts between different versions’ implementations
- Success criteria:
Runtime dynamically handles different field sets
No version explosion in runtime library
Clear semantics for missing fields across versions