diff options
| author | 2026-10-15 09:56:19 +0330 | |
|---|---|---|
| committer | 2026-10-15 09:56:19 +0330 | |
| commit | 6bbac2edf7c50dac4d755a364b6dfd16471284d7 (patch) | |
| tree | e83b493f55ed07287cd2ab4e3a940c04871d9a14 /src/compiler/types.zc | |
| parent | analyzer: use-after-end messages name the borrower, the owner and how the own... (diff) | |
analyzer: check borrow returns of forward-called functions at the unit's end; borrows clause for prototypes, definitions, externs and function types, checked against the body
Diffstat (limited to 'src/compiler/types.zc')
| -rw-r--r-- | src/compiler/types.zc | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/src/compiler/types.zc b/src/compiler/types.zc index 81547a5..322d0fd 100644 --- a/src/compiler/types.zc +++ b/src/compiler/types.zc @@ -105,6 +105,35 @@ word tsized(char* name, int bytes, int sgn) { return t; } // the function type with this return, parameter list and signature. +// ---- borrow returns ---- +// `borrows s` after a parameter list says the result is a borrow of parameter s +// (several, comma separated, in a declaration). a parameter is named, or given by +// its position from 0 where it has no name (an extern, a function type). the mask +// lives in bits 50 to 61 of the signature, so a function type carries it too. +const int SIG_BORROWS = 50; +int sig_borrows(int sig) { return (sig >> SIG_BORROWS) & 4095; } +// the declared borrow mask of a call's callee: its symbol's signature, or the function type. +int callee_borrows(int s, word ft) { + if (s >= 0 && s < nsym && (sflag[s] & F_SIG)) return sig_borrows(ssig[s]); + if (ft && ft[0] == TY_FN) return sig_borrows(ft[5]); + return 0; +} +int borrows_clause(char** names, int np, int many) { + int mask = 0, k; + if (tk != T_ID || !rt.eq_w(tv, "borrows")) return 0; + next(); + while (1) { + k = 0 - 1; + if (tk == T_NUM) { if (tv >= 0 && tv < np) k = tv; } + else if (tk == T_ID && names) { int j = 0; while (j < np) { if (names[j] && rt.eq_w(names[j], tv)) k = j; j++; } } + if (k < 0) { serr("borrows names a parameter, by name or by its position from 0"); next(); return mask; } + if (k >= 12) serr("only the first 12 parameters can be borrowed by the result"); + else mask = mask | (1 << k); + next(); + if (!many || !accept(s_comma)) break; + } + return mask; +} word tfn(int ret, int np, word ps, int sig) { int i = 0, j; word t; while (i < ntl) { @@ -388,7 +417,8 @@ int ptype() { } } expect(s_rp); - t = tfn(t, np, ps, np + np + tags * 64); + tag = borrows_clause(0, np, 0); + t = tfn(t, np, ps, np + np + tags * 64 + (tag << SIG_BORROWS)); } ht_note(start, toff, t); return t; |
