commit 60276b9715bb154938ceaa813300509638de1835
parent 767a4eea6cde918505b76da9bde57641e0e0aa34
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 1 Aug 2016 14:52:08 +0200
[cc1] Call decay() in postfix()
Calling decay() in postfix avoids calling it across a lot of different functions
in expr.c, but it has the problem that it makes a bit harder don't decay in the case
of sizeof. This patch is a good compromise between them, because it adds a parameter
to unary() and postfix() and callers set it to the correct value to avoid decaying.
Diffstat:
2 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/cc1/expr.c b/cc1/expr.c
@@ -144,9 +144,6 @@ null(Node *np)
static Node *
chkternary(Node *yes, Node *no)
{
- yes = decay(yes);
- no = decay(no);
-
/*
* FIXME:
* We are ignoring type qualifiers here,
@@ -386,9 +383,6 @@ compare(char op, Node *lp, Node *rp)
{
Type *ltp, *rtp;
- lp = decay(lp);
- rp = decay(rp);
-
ltp = lp->type;
rtp = rp->type;
@@ -438,7 +432,6 @@ negate(Node *np)
static Node *
exp2cond(Node *np, char neg)
{
- np = decay(np);
if (np->type->prop & TAGGREG) {
errorp("used struct/union type value where scalar is required");
np = constnode(zero);
@@ -491,7 +484,6 @@ free_np:
static Node *
content(char op, Node *np)
{
- np = decay(np);
switch (BTYPE(np)) {
case ARY:
case FTN:
@@ -519,7 +511,7 @@ array(Node *lp, Node *rp)
if (!(lp->type->prop & TINTEGER) && !(rp->type->prop & TINTEGER))
error("array subscript is not an integer");
- np = arithmetic(OADD, decay(lp), decay(rp));
+ np = arithmetic(OADD, lp, rp);
tp = np->type;
if (tp->op != PTR)
errorp("subscripted value is neither array nor pointer");
@@ -529,7 +521,7 @@ array(Node *lp, Node *rp)
static Node *
assignop(char op, Node *lp, Node *rp)
{
- if ((rp = convert(decay(rp), lp->type, 0)) == NULL) {
+ if ((rp = convert(rp, lp->type, 0)) == NULL) {
errorp("incompatible types when assigning");
return lp;
}
@@ -563,17 +555,22 @@ incdec(Node *np, char op)
static Node *
address(char op, Node *np)
{
- Node *new;
+ Node *new, *left;
- if (BTYPE(np) != FTN) {
- chklvalue(np);
- if (np->sym && (np->sym->flags & SREGISTER))
- errorp("address of register variable '%s' requested", yytext);
- if (np->op == OPTR) {
- Node *new = np->left;
- free(np);
- return new;
- }
+ /*
+ * ansi c accepts & applied to a function name, and it generates
+ * a function pointer
+ */
+ left = np->left;
+ if (np->op == OADDR && left->sym && left->type->op == FTN)
+ return np;
+ chklvalue(np);
+ if (np->sym && (np->sym->flags & SREGISTER))
+ errorp("address of register variable '%s' requested", yytext);
+ if (np->op == OPTR) {
+ Node *new = np->left;
+ free(np);
+ return new;
}
new = node(op, mktype(np->type, PTR, 0, NULL), np, NULL);
@@ -585,7 +582,6 @@ address(char op, Node *np)
static Node *
negation(char op, Node *np)
{
- np = decay(np);
if (!(np->type->prop & TARITH) && np->type->op != PTR) {
errorp("invalid argument of unary '!'");
freetree(np);
@@ -636,7 +632,7 @@ primary(void)
sym->flags |= SHASINIT;
emit(ODECL, sym);
emit(OINIT, np);
- np = decay(varnode(sym));
+ np = varnode(sym);
next();
break;
case CONSTANT:
@@ -688,7 +684,7 @@ arguments(Node *np)
toomany = 0;
do {
- arg = decay(assign());
+ arg = assign();
argtype = *targs;
if (argtype == ellipsistype) {
n = 0;
@@ -728,13 +724,15 @@ no_pars:
}
static Node *
-postfix(Node *lp)
+postfix(Node *lp, int issizeof)
{
Node *rp;
if (!lp)
lp = primary();
for (;;) {
+ if (!issizeof)
+ lp = decay(lp);
switch (yytoken) {
case '[':
next();
@@ -762,7 +760,7 @@ postfix(Node *lp)
}
}
-static Node *unary(void);
+static Node *unary(int);
static Type *
typeof(Node *np)
@@ -788,7 +786,7 @@ sizeexp(void)
tp = typename();
break;
default:
- tp = typeof(unary());
+ tp = typeof(unary(1));
break;
}
expect(')');
@@ -798,7 +796,7 @@ sizeexp(void)
static Node *cast(void);
static Node *
-unary(void)
+unary(int issizeof)
{
Node *(*fun)(char, Node *);
char op;
@@ -807,7 +805,7 @@ unary(void)
switch (yytoken) {
case SIZEOF:
next();
- tp = (yytoken == '(') ? sizeexp() : typeof(unary());
+ tp = (yytoken == '(') ? sizeexp() : typeof(unary(1));
if (!(tp->prop & TDEFINED))
errorp("sizeof applied to an incomplete type");
return sizeofnode(tp);
@@ -815,14 +813,14 @@ unary(void)
case DEC:
op = (yytoken == INC) ? OA_ADD : OA_SUB;
next();
- return incdec(unary(), op);
+ return incdec(unary(issizeof), op);
case '!': op = 0; fun = negation; break;
case '+': op = OADD; fun = numericaluop; break;
case '-': op = ONEG; fun = numericaluop; break;
case '~': op = OCPL; fun = integeruop; break;
case '&': op = OADDR; fun = address; break;
case '*': op = OPTR; fun = content; break;
- default: return postfix(NULL);
+ default: return postfix(NULL, issizeof);
}
next();
@@ -837,7 +835,7 @@ cast(void)
static int nested;
if (!accept('('))
- return unary();
+ return unary(0);
switch (yytoken) {
case TQUALIFIER:
@@ -866,7 +864,7 @@ cast(void)
rp = expr();
--nested;
expect(')');
- rp = postfix(rp);
+ rp = postfix(rp, 0);
break;
}
diff --git a/cc1/tests/test001.c b/cc1/tests/test001.c
@@ -9,13 +9,13 @@ X4 I F "printf
G6 I F "main
{
\
-V8 K #N13
-Y7 V8 " (
+V9 K #N13
+Y8 V9 " (
#"hello world
#K0A
#K00
)
- X4 Y7 'P pP cI
+ X4 Y8 'P pP cI
h #I0
}
*/