diff options
| -rw-r--r-- | docs/SPEC.md | 4 | ||||
| -rw-r--r-- | src/compiler/builtins.zc | 3 | ||||
| -rw-r--r-- | tests/conformance/9-appendix-b/b2_14_len_char_ptr_typecheck_off.zc | 4 | ||||
| -rw-r--r-- | tests/conformance/known.txt | 1 |
4 files changed, 6 insertions, 6 deletions
diff --git a/docs/SPEC.md b/docs/SPEC.md index 128f961..dd04cde 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -490,7 +490,7 @@ pn(pop(a)); pn(a.pop()); pn(a.len()); // 4 3 2 a[2]; // zy: index 2 out of range (length 2) ``` -3.13.5 the length of a non-array (`len("text")` on a `char*`) is unspecified when `typecheck` is off (it reads word 0) and error: len needs an array under `typecheck on;`. use `rt.len_w` for word strings and `len` for `bstr`. +3.13.5 `len` on a `char*` is error: len needs an array, not a char* when `typecheck` is off, and error: len needs an array under `typecheck on;`. use `rt.len_w` for word strings and `len` for `bstr`. ### 3.14 constant expressions @@ -1117,7 +1117,7 @@ each item gives a minimal program, the expected behavior (per this spec) and the 11. fixed (1.2.2): an unterminated `/* ...` comment was accepted silently; it is error: unterminated comment. (an unterminated string literal is still only reported as a later syntax error.) 12. settled (3.2.3): `x as int * y` parses `int*` as the type. this is the rule (the type is read greedily, as zc0 does too), so the program is a syntax error. 13. fixed (5.2.1): a prototype's parameters may be unnamed (`int f(int, int*);`). a lone type name counts as a type only in a prototype; with a body it is still the parameter's name, and an unnamed typed parameter there is `a parameter needs a name`. -14. `len(s)` on a `char*` returns word 0 of the string when `typecheck` is off. +14. fixed (3.13.5): `len(s)` on a `char*` used to return word 0 of the string when `typecheck` was off; it is now a compile error. 15. duplicate `case` labels are not diagnosed (4.7.2). 16. a local `const` cannot be used in a constant expression (b.1.7). 17. fixed: a bad float or character literal in a function's first statement was not reported (1.4). diff --git a/src/compiler/builtins.zc b/src/compiler/builtins.zc index 6dc586a..cbc380e 100644 --- a/src/compiler/builtins.zc +++ b/src/compiler/builtins.zc @@ -706,7 +706,8 @@ int array_len(word t) { return 0; } if (t[0] == TY_ARR) { op(O_DROP); lit(t[3]); } - else { tcneed(t[0] == TY_DYN || t == tword, "len needs an array", t); if (argloc >= 0) { op(O_DROP); vaddr(o3cache[argloc] + 1); op(O_LD); } else if (o3on && t[0] == TY_DYN) op(O_LD); else callname(s_dlen); } + else { if (!tc_on && t[0] == TY_PTR && t[4][0] == TY_CHAR) serr("len needs an array, not a char* (use rt.len_w, or a bstr)"); // b.2.14: it would read word 0 + tcneed(t[0] == TY_DYN || t == tword, "len needs an array", t); if (argloc >= 0) { op(O_DROP); vaddr(o3cache[argloc] + 1); op(O_LD); } else if (o3on && t[0] == TY_DYN) op(O_LD); else callname(s_dlen); } xty = tint; xlenloc = -1; xstamp = 0; if (a >= 0 && t[0] == TY_DYN && t[3]) xlenloc = a; // the whole expression is len of a fixed array diff --git a/tests/conformance/9-appendix-b/b2_14_len_char_ptr_typecheck_off.zc b/tests/conformance/9-appendix-b/b2_14_len_char_ptr_typecheck_off.zc index b0d0d45..0953328 100644 --- a/tests/conformance/9-appendix-b/b2_14_len_char_ptr_typecheck_off.zc +++ b/tests/conformance/9-appendix-b/b2_14_len_char_ptr_typecheck_off.zc @@ -1,5 +1,5 @@ -// expect: 3/ -// spec appendix b.2.14: len(char*) with typecheck off returns word 0 +// expect error: len needs an array, not a char* +// spec 3.13.5 and appendix b.2.14: len on a char* is an error with typecheck off too include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } typecheck off; diff --git a/tests/conformance/known.txt b/tests/conformance/known.txt index 2fbd331..8e6ea97 100644 --- a/tests/conformance/known.txt +++ b/tests/conformance/known.txt @@ -3,7 +3,6 @@ # appendix b.2.8 (a global named in an initializer is its address) is documented behavior per 5.3.2 and 3.14.2: no entry 4-statements/o3_outside_function_ordinary_block.zc zy c top-level o3 { } is rejected; spec 4.10.2 says it is an ordinary block 9-appendix-b/b2_10_recovery_hides_errors.zc zy c appendix b.2.10 confirmed; by design per 8.2 -9-appendix-b/b2_14_len_char_ptr_typecheck_off.zc zy c appendix b.2.14 confirmed, but spec 3.13.5 leaves it unspecified 9-appendix-b/b2_15_duplicate_case.zc zy c appendix b.2.15 confirmed; 4.7.2 says duplicates are allowed 9-appendix-b/b2_16_local_const_in_const_expr.zc zy c appendix b.2.16 confirmed; 3.14.2 documents it 1-source/ident_tags_as_variables_glued_star.zc zc0 b u*d with visible u and d is read as a recast (no code); zy follows 1.6.3 |
