kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 7f8eab153bbe7861f2466909b1e0b71ad9488730
parent aaf3e90b91d0938e78ff4af28c7fdc52f12bc3c4
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 10 Jun 2026 07:49:36 -0700

cleanup: I.3 — add pcg_retag_keep_flags op for shadow-stack retags

Two parse_expr.c sites poked p->cg_type_stack[...] directly to change a
slot's type while keeping its value flags + lvalue aux (struct
unqualification; narrowing a compound-assign LHS) because no op expressed
that. Add pcg_retag_keep_flags(p, depth, ty) and route both sites through
it. Semantically identical (same array write); removes the bridge poke.

test-parse (3880+128), test-cg-api (211), test-toy (1394/0/33) green.

Diffstat:
Mdoc/plan/TODO.md | 2--
Mlang/c/parse/cg_adapter.c | 9+++++++++
Mlang/c/parse/cg_adapter.h | 1+
Mlang/c/parse/parse_expr.c | 4++--
4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/doc/plan/TODO.md b/doc/plan/TODO.md @@ -109,8 +109,6 @@ Add new deferred fixes below as they are discovered. bridge — higher risk; needs care.) - **I.2 — two parallel C-6.7.9 initializer walkers** (`lang/c/parse/parse_init.c:648-777`) re-encode the same traversal grammar. Factor a single grammar driver + leaf vtable. -- **I.3 — `cg_adapter` callers poke the shadow-stack array directly** because no - retag-keep-flags op exists. Add the op. (Pairs with I.1.) - **I.4 — opt passes re-hand-roll the centralized operand-walk.** (The `ranges_overlap` trampoline part is fixed.) diff --git a/lang/c/parse/cg_adapter.c b/lang/c/parse/cg_adapter.c @@ -183,6 +183,15 @@ void pcg_retag_top(Parser* p, const Type* ty) { } } +/* Replace the type of the slot `depth` below the top (depth 0 == top) while + * preserving its value flags and lvalue aux. Unlike pcg_retag_top this keeps + * the slot's lvalue-ness/bitfield/aux intact — used where only the C type + * changes (e.g. struct unqualification, narrowing a compound-assign LHS). */ +void pcg_retag_keep_flags(Parser* p, u32 depth, const Type* ty) { + if (p->cg_type_sp > depth) + p->cg_type_stack[p->cg_type_sp - 1u - depth] = ty; +} + int pcg_top_is_bitfield(Parser* p) { return p->cg_type_sp && (p->cg_value_flags[p->cg_type_sp - 1u] & PCG_VALUE_BITFIELD) != 0; diff --git a/lang/c/parse/cg_adapter.h b/lang/c/parse/cg_adapter.h @@ -237,6 +237,7 @@ KitCgMemAccess pcg_mem(Parser*, const Type*); const Type* pcg_top_type(Parser*); const Type* pcg_top2_type(Parser*); void pcg_retag_top(Parser*, const Type*); +void pcg_retag_keep_flags(Parser*, u32 depth, const Type*); void pcg_push_type(Parser*, const Type*); void pcg_drop_type(Parser*); void pcg_dup_type(Parser*); diff --git a/lang/c/parse/parse_expr.c b/lang/c/parse/parse_expr.c @@ -1033,7 +1033,7 @@ void to_rvalue(Parser* p) { is_lvalue && lv && (lv->offset != 0 || lv->scale != 0 || lv->is_subobject || lv->base_kind == PCG_LV_BASE_POINTER_RV); - p->cg_type_stack[p->cg_type_sp - 1u] = uty; + pcg_retag_keep_flags(p, 0, uty); if (materialize) { pcg_addr(p); pcg_deref(p, uty); @@ -3536,7 +3536,7 @@ void parse_assign_expr(Parser* p) { } } coerce_top_to_type(p, lhs); - if (p->cg_type_sp >= 2) p->cg_type_stack[p->cg_type_sp - 2u] = lhs; + pcg_retag_keep_flags(p, 1, lhs); pcg_store(p); }