aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/expr.zc7
-rw-r--r--tests/conformance/1-source/ident_tags_global_glued_star.zc8
2 files changed, 14 insertions, 1 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc
index c8cb11a..ffb90a7 100644
--- a/src/compiler/expr.zc
+++ b/src/compiler/expr.zc
@@ -1507,12 +1507,17 @@ int postfix_tail(int c) {
}
return c;
}
+// a global variable or array named u, m or d: then u*x is a multiplication (spec 1.6.3)
+int tag_is_global(int n) {
+ int s = lookup(n);
+ return s >= 0 && (skind[s] == K_GVAR || skind[s] == K_GARR);
+}
// prefix operators: the u*x / d*x / m*x recasts (the star has to touch the
// tag), casts like (int)x and (node*)x, dereference, address-of, prefix ++ and
// --, 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) && findloc(tv) < 0) { // u*x, d*x, m*x: recast only when * is glued and the tag is not a local's name
+ if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d) && findloc(tv) < 0 && !tag_is_global(tv)) { // 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/1-source/ident_tags_global_glued_star.zc b/tests/conformance/1-source/ident_tags_global_glued_star.zc
new file mode 100644
index 0000000..516f9a3
--- /dev/null
+++ b/tests/conformance/1-source/ident_tags_global_glued_star.zc
@@ -0,0 +1,8 @@
+// expect: 12/10/
+// spec 1.6.3: u*x and m*x are not recasts when u or m is a visible global variable
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int u = 3;
+int m = 5;
+fn main() { int d = 4; int k = 2; pn(u*d); pn(m*k); return 0; }
+// zc0: skip