scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit bcd4c47c01e02e5c9a9ae3ce749629510f7ecf5c
parent e6205dfae4d600aa978040fdec8596a4ac495ffb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 18 Jan 2023 20:21:21 +0100

cc1: Improve constness of address operator

When the address of a variable is taken (or when it is decayed)
there are cases when constant values are generated and we were
not considering the OFIELD operator.

Diffstat:
Msrc/cmd/cc/cc1/expr.c | 42++++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/src/cmd/cc/cc1/expr.c b/src/cmd/cc/cc1/expr.c @@ -215,6 +215,18 @@ chklvalue(Node *np) errorp("invalid use of void expression"); } +static Node * +chkconstaddr(Node *var, Node *addr) +{ + if (var->sym && var->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE) + || var->op == OFIELD && var->left->op == OSYM + || var->op == OFIELD && (var->left->flags & NCONST)) { + addr->flags |= NCONST; + } + + return addr; +} + Node * decay(Node *np) { @@ -225,26 +237,21 @@ decay(Node *np) case ARY: DBG("EXPR decay ary"); tp = tp->type; - if (np->op == OPTR) { - new = np->left; - free(np); - new->type = mktype(tp, PTR, 0, NULL); - return new; - } - break; + if (np->op != OPTR) + goto new_node; + new = np->left; + free(np); + new->type = mktype(tp, PTR, 0, NULL); + return chkconstaddr(new, new); case FTN: DBG("EXPR decay function"); - break; + new_node: + new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL); + new->flags |= NDECAY; + return chkconstaddr(np, new); default: return np; } - - new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL); - if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE)) - new->flags |= NCONST; - new->flags |= NDECAY; - - return new; } static Node * @@ -601,9 +608,8 @@ dont_check_lvalue: if (sym && (sym->flags & SREGISTER)) errorp("address of register variable '%s' requested", yytext); new = node(op, mktype(tp, PTR, 0, NULL), np, NULL); - if (sym && sym->flags & (SGLOBAL|SLOCAL|SPRIVATE)) - new->flags |= NCONST; - return new; + + return chkconstaddr(np, new); } static Node *