[Fix] (Pipe, Purity): end a declared verb honestly, and gate the header MG_State now includes

- MGPipeLeaveVerb() bumps the serial and puts the current verb back to none, so a test that
  drives a backend helper directly stops declaring where it says it stops and a later
  unguarded read aborts as "<Field>@<none>" instead of naming an unrelated verb
- check_include_closure.py gains a fourth probe: F2 put MGP_NOTE_MUTATION into frontend
  mutators, so MG_State includes MG_Pipe/PipeMutation.h and that header must never reach
  back into MG_State, MG_Impl or a backend
This commit is contained in:
2026-09-06 06:15:56 -04:00
parent ef6227e19b
commit 62a7786184
4 changed files with 44 additions and 5 deletions
+10
View File
@@ -552,6 +552,16 @@ namespace MobileGL::MG_Pipe {
ctx->RecordError(code, Move(info));
}
void MGPipeLeaveVerb() {
PipeInputs& inputs = gPipeInputs;
#if MOBILEGL_PIPE_POISON
// Same bump the next fill would make, without a verb to fill from: no field is
// stamped, so every stamp this verb made falls behind the serial.
++MGPipeFillAccess::Filled(inputs).CurrentVerbSerial;
#endif
MGPipeFillAccess::SetVerb(inputs, MGPipeVerb::kVerbCount);
}
// ---- the filler ----
void MGPipeFillForVerb(MGPipeVerb verb) {
PipeInputs& inputs = gPipeInputs;
+9
View File
@@ -24,6 +24,15 @@ namespace MobileGL::MG_Pipe {
// runs the entry compare against a second snapshot (P1 brief D8).
void MGPipeFillForVerb(MGPipeVerb verb);
// Ends the verb in flight without starting another: bumps the serial, so every field the
// verb stamped goes stale, and puts the current verb back to "none", so a read made after
// it aborts as Fatal{UnmigratedPipeInput, "<Field>@<none>"} - which is what such a read
// is - instead of naming whichever verb happened to be filled last. Nothing in the GL
// entry points calls this: a real verb is always followed by the next verb's fill. It
// exists for a caller that drives a backend helper directly and wants its declaration to
// stop where it says it stops (MG_Test/ScopedPipeVerb.h).
void MGPipeLeaveVerb();
// PipeFill.cpp. Negative control B (P1 brief D6): the filler withholds the STAMP - never
// the value - of `field` at `verb`, so that verb's read of it is
// Fatal{UnmigratedPipeInput, "Field@Verb"} while every other verb is unaffected. The