test: document setjmp volatile-analysis in firmware host harness loop

Add a comment next to the per-test setjmp(g_test_jmp) guard in main()'s
loop recording the C11 7.13.2.1 volatile analysis: the loop index i is
read in the post-longjmp path (g_tests[i].name) but is not modified
between the setjmp() call and a possible longjmp() — the body only reads
i, and the only write is the for-loop increment, which runs after control
returns. So no volatile qualifier is needed. (bf-2ftl)

Co-Authored-By: Claude <noreply@anthropic.com>
Bead-Id: bf-2ftl
This commit is contained in:
jedarden 2026-07-03 12:42:09 -04:00
parent c66f62e616
commit 8fbc2e82c3

View file

@ -234,6 +234,25 @@ int main(void)
int failed = 0;
for (int i = 0; i < g_test_count; i++) {
/*
* Per-test recovery guard. setjmp() establishes the longjmp() target
* that test_record_failure() jumps into on a failed assertion. On the
* direct call setjmp() returns 0 and the body runs as before; on a
* longjmp() return it yields non-zero and we take the else branch
* the body is NOT re-invoked, the loop just falls through to the next
* i. That is the whole point: a failure in test N never blocks N+1.
*
* volatile analysis (C11 7.13.2.1): an automatic variable modified
* between setjmp() and longjmp() AND read after the longjmp returns
* has indeterminate value unless it is volatile-qualified. The loop
* index i IS read in the post-longjmp path (g_tests[i].name in the
* else branch), so the question is whether i is modified between the
* setjmp() call and a possible longjmp(). It is not: between them the
* body only READS i (g_tests[i].fn()), and the only write to i is the
* for-loop increment, which runs AFTER control returns here (whether
* via a normal body return or the longjmp). So no volatile is needed
* on i confirmed safe.
*/
if (setjmp(g_test_jmp) == 0) {
g_tests[i].fn();
printf("PASS: %s\n", g_tests[i].name);