wcc: drop @test fns from non-T builds, both stages (harec check.c:3941)
Splice @test N_FNDECLs out of the unit after the body-check passes, mirroring harec's checked-but-not-emitted: a broken @test body still errors loudly in non-T; @test-free units are emission-unchanged. 910/997 table rows pin keep/test x non-T/-T, head+consecutive unlink, undef-body reject, and plain-calls-dropped loud link-fail. w6c+wwdump combined.ww regen. (#6-team)
This commit is contained in:
@@ -121,6 +121,132 @@ static const struct {
|
||||
{ "test/wcc/data/attest_badsig.ww", "non-void @test" },
|
||||
};
|
||||
|
||||
/*
|
||||
* #6: each row asserts whether a symbol's TEXT def appears in the asm
|
||||
* `<comp>` emits for attest_nondrop.ww in a given mode. A @test fn is
|
||||
* spliced out of a non-test build (harec ref/harec/src/check.c:3941 —
|
||||
* checked but never emitted) and kept under -T (the synth entry calls
|
||||
* it); a plain fn is always emitted.
|
||||
*/
|
||||
static const struct {
|
||||
const char *sym; /* TEXT label to grep for */
|
||||
int testmode; /* 1 => -T, 0 => plain build */
|
||||
int present; /* expected: 1 present, 0 absent */
|
||||
const char *what;
|
||||
} nondrop_rows[] = {
|
||||
{ "data.nondrop_keep", 0, 1, "plain fn kept non-T" },
|
||||
{ "data.nondrop_test_a", 0, 0, "head @test dropped non-T" },
|
||||
{ "data.nondrop_test_b", 0, 0, "mid @test dropped non-T" },
|
||||
{ "data.nondrop_test_c", 0, 0, "consecutive @test dropped non-T" },
|
||||
{ "data.nondrop_keep", 1, 1, "plain fn kept under -T" },
|
||||
{ "data.nondrop_test_a", 1, 1, "head @test kept under -T" },
|
||||
{ "data.nondrop_test_b", 1, 1, "mid @test kept under -T" },
|
||||
{ "data.nondrop_test_c", 1, 1, "consecutive @test kept under -T" },
|
||||
};
|
||||
|
||||
/* nondrop — compile attest_nondrop.ww plain and `-T`, then assert each
|
||||
* row's TEXT def is present/absent. */
|
||||
static int
|
||||
nondrop(const char *bin, const char *comp)
|
||||
{
|
||||
int pid = getpid();
|
||||
char plain[256], tee[256], cmd[4096];
|
||||
snprintf(plain, sizeof plain, "/tmp/at910nd_%s_p_%d.s", comp, pid);
|
||||
snprintf(tee, sizeof tee, "/tmp/at910nd_%s_t_%d.s", comp, pid);
|
||||
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/%s test/wcc/data/attest_nondrop.ww -o %s 2>/dev/null",
|
||||
bin, comp, plain);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "910 FAIL: %s non-T nondrop compile\n", comp);
|
||||
return 1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/%s -T test/wcc/data/attest_nondrop.ww -o %s 2>/dev/null",
|
||||
bin, comp, tee);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "910 FAIL: %s -T nondrop compile\n", comp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
for (size_t i = 0; i < sizeof nondrop_rows / sizeof nondrop_rows[0]; i++) {
|
||||
const char *f = nondrop_rows[i].testmode ? tee : plain;
|
||||
snprintf(cmd, sizeof cmd, "grep -q '^TEXT %s,' %s",
|
||||
nondrop_rows[i].sym, f);
|
||||
int found = runwait(cmd) == 0;
|
||||
if (found != nondrop_rows[i].present) {
|
||||
fprintf(stderr, "910 FAIL: %s — %s: %s %s (expected %s)\n",
|
||||
comp, nondrop_rows[i].what, nondrop_rows[i].sym,
|
||||
found ? "present" : "absent",
|
||||
nondrop_rows[i].present ? "present" : "absent");
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlink(plain); unlink(tee);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* reject_plain — `<comp> <fixture>` (NON-T) must exit nonzero. Pins that
|
||||
* a @test body is type-checked before the #6 splice drops it: an
|
||||
* undefined symbol in the body is caught loud even though the fn never
|
||||
* reaches codegen (harec checks at :3913, drops at :3941). */
|
||||
static int
|
||||
reject_plain(const char *bin, const char *comp, const char *fixture,
|
||||
const char *what)
|
||||
{
|
||||
char cmd[4096];
|
||||
snprintf(cmd, sizeof cmd, "%s/%s %s -o /dev/null 2>/dev/null",
|
||||
bin, comp, fixture);
|
||||
if (runwait(cmd) == 0) {
|
||||
fprintf(stderr, "910 FAIL: %s (non-T) accepted %s "
|
||||
"(expected reject)\n", comp, what);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* linkfail — a plain fn calling a @test fn, built non-T: compile +
|
||||
* assemble succeed, but the link MUST fail (the dropped @test def leaves
|
||||
* the call's symbol dangling — harec-faithful loud failure, never a
|
||||
* silent mis-link). Linker behavior is stage-independent, so cstage
|
||||
* suffices; 997's byte-id proves the wwstage .s is identical. */
|
||||
static int
|
||||
linkfail(const char *bin, const char *comp)
|
||||
{
|
||||
int pid = getpid();
|
||||
char asmf[256], obj[256], exe[256], rt[1024], cmd[4096];
|
||||
snprintf(asmf, sizeof asmf, "/tmp/at910lf_%s_%d.s", comp, pid);
|
||||
snprintf(obj, sizeof obj, "/tmp/at910lf_%s_%d.o", comp, pid);
|
||||
snprintf(exe, sizeof exe, "/tmp/at910lf_%s_%d.exe", comp, pid);
|
||||
snprintf(rt, sizeof rt, "%s/../lib/libwwrt.a", bin);
|
||||
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/%s test/wcc/data/attest_calldropped.ww -o %s 2>/dev/null",
|
||||
bin, comp, asmf);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "910 FAIL: %s non-T calldropped compile\n", comp);
|
||||
return 1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null", bin, obj, asmf);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "910 FAIL: w6a calldropped\n");
|
||||
unlink(asmf);
|
||||
return 1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s %s 2>/dev/null",
|
||||
bin, exe, obj, rt);
|
||||
int rc = 0;
|
||||
if (runwait(cmd) == 0) {
|
||||
fprintf(stderr, "910 FAIL: calldropped linked (expected "
|
||||
"undefined-reference to the dropped @test sym)\n");
|
||||
rc = 1;
|
||||
}
|
||||
unlink(asmf); unlink(obj); unlink(exe);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
@@ -131,7 +257,12 @@ main(void)
|
||||
for (size_t i = 0; i < sizeof rejects / sizeof rejects[0]; i++)
|
||||
if (reject(bin, "w6c", rejects[i].fixture, rejects[i].what) != 0)
|
||||
return 1;
|
||||
if (nondrop(bin, "w6c") != 0) return 1;
|
||||
if (reject_plain(bin, "w6c", "test/wcc/data/attest_undefbody.ww",
|
||||
"undefined symbol in @test body") != 0) return 1;
|
||||
if (linkfail(bin, "w6c") != 0) return 1;
|
||||
|
||||
printf("@test -T: run ok + user-main and bad-signature rejected\n");
|
||||
printf("@test -T: run ok + user-main and bad-signature rejected + "
|
||||
"non-T @test drop + checked-body + dangling-call link-fail (#6)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user