From 5a4f3885edafe289dce17ec8b53a8fc188b9e146 Mon Sep 17 00:00:00 2001 From: zinc Date: Wed, 14 Oct 2026 15:53:37 +0330 Subject: capture_scan: restore panic after the dry scan, so a bad literal in a function's first statement is reported --- src/compiler/expr.zc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/compiler/expr.zc') diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc index 40de6ef..bcb92da 100644 --- a/src/compiler/expr.zc +++ b/src/compiler/expr.zc @@ -538,7 +538,7 @@ int enhcall(int s) { // scan with the compiler lexer, restoring its source and lookahead. only functions containing a closure // need cells; their scalars get cells from declaration time, so loop back edges and earlier references agree. int capture_scan() { - word old, f; int depth = 1, found = 0, docs = docs_on, record = grec; + word old, f; int depth = 1, found = 0, docs = docs_on, record = grec, sp = panic; if (isp < 0 || R_SRC[isp * 32] == 0 || !is_op(s_lb)) return 0; old = R_SRC + isp * 32; src_push(1, capture_dummy, 0, 0); old = R_SRC + (isp - 1) * 32; f = R_SRC + isp * 32; @@ -550,7 +550,7 @@ int capture_scan() { else if (is_op(s_rb)) depth--; else if (is_id(s_fn)) { peek(); if (pk_tk == T_OP && (pk_tv == s_lp || pk_tv == s_colon)) found = 1; } } - dry--; src_pop(); docs_on = docs; grec = record; return found; + dry--; src_pop(); docs_on = docs; grec = record; panic = sp; return found; // a lexer error in the dry scan must not leave panic set for the real parse } int capture_cell(int i, int copy) { if (!capture_enabled || o3on || (ltag[i] & 16) || larr[i] || local_cell[i]) return 0; -- cgit v1.2.3 From 0e110746d91d48c9a40440ab8807c5e6d23a3b1c Mon Sep 17 00:00:00 2001 From: zinc Date: Wed, 14 Oct 2026 15:54:17 +0330 Subject: unary: u*x, m*x, d*x are not recasts when the tag names a visible local (spec 1.6.3) --- src/compiler/expr.zc | 2 +- tests/conformance/known.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src/compiler/expr.zc') diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc index bcb92da..c0e9c91 100644 --- a/src/compiler/expr.zc +++ b/src/compiler/expr.zc @@ -1510,7 +1510,7 @@ int postfix_tail(int c) { // --, and any unary operator a program added (- ! ~ built in). int unary() { int c, un, t, place, constant, value; word storage, dependency; - if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d)) { // u*x, d*x, m*x: recast only when * is glued + if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d) && findloc(tv) < 0) { // u*x, d*x, m*x: recast only when * is glued and the tag is not a local's name peek(); if (pk_tk == T_OP && pk_tv == s_star && pq_gl[0]) { t = S_M; if (tv == s_u) t = S_U; if (tv == s_d) t = S_D; diff --git a/tests/conformance/known.txt b/tests/conformance/known.txt index 2412378..94d7869 100644 --- a/tests/conformance/known.txt +++ b/tests/conformance/known.txt @@ -1,6 +1,5 @@ # understood conformance failures: PATH IMPL CLASS reason # class a: self-hosted compiler bug; b: zc0 deviation (appendix a/b); c: spec issue to settle -1-source/ident_tags_as_variables_glued_star.zc zy a u*d with visible variables u and d is taken as a recast, not a multiplication (spec 1.6.3) 1-source/lit_bstr_cast_to_int_pointer.zc zy a the bstr flag leaks into an int* local, so p[0] reads a byte 2-types/typecheck_off_void_return_value_ok.zc zy a void f() { return 3; } yields 3, not 0 (spec 4.8.3) 3-expressions/call_24_parameters.zc zy a the parameter limit is 23, not 24 (decl.zc; closures 19) -- cgit v1.2.3 From 39857ceb4ece09eb739fe17895ec807e3e04f602 Mon Sep 17 00:00:00 2001 From: zinc Date: Wed, 14 Oct 2026 15:55:01 +0330 Subject: casts: a cast clears the byte-string flag unless the type is bstr, so (int*)s indexes words --- src/compiler/expr.zc | 1 + tests/conformance/known.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src/compiler/expr.zc') diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc index c0e9c91..3829ecf 100644 --- a/src/compiler/expr.zc +++ b/src/compiler/expr.zc @@ -1534,6 +1534,7 @@ int unary() { else if (xfloat && isnum(t)) { op(OP_F2I); xfloat = 0; } else xfloat = 0; if (tbytes(t) && !samesz(t, xty)) { tnorm(t); xconst = 0; } // (u8)x cuts the value to size + xstr = t == tbstr; // (int*)s is a word pointer, not a byte string if_value = 0; xty = t; lv = 0; lvk = LV_NONE; xzero = 0; xbor = -1; return C_PLAIN; diff --git a/tests/conformance/known.txt b/tests/conformance/known.txt index 94d7869..18492fd 100644 --- a/tests/conformance/known.txt +++ b/tests/conformance/known.txt @@ -1,6 +1,5 @@ # understood conformance failures: PATH IMPL CLASS reason # class a: self-hosted compiler bug; b: zc0 deviation (appendix a/b); c: spec issue to settle -1-source/lit_bstr_cast_to_int_pointer.zc zy a the bstr flag leaks into an int* local, so p[0] reads a byte 2-types/typecheck_off_void_return_value_ok.zc zy a void f() { return 3; } yields 3, not 0 (spec 4.8.3) 3-expressions/call_24_parameters.zc zy a the parameter limit is 23, not 24 (decl.zc; closures 19) 3-expressions/call_24_parameters_prototype.zc zy a the parameter limit is 23, not 24 (decl.zc; closures 19) -- cgit v1.2.3