commit 4ed4dac59ff781ba4bd54db585c2384595e175dc
parent eb28f98e61cf995a7c1f9c85faf3431438018e03
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 8 Oct 2024 12:51:19 +0200
cc1: Fix sizeof expressions
The commit c863f707 tried to fix expressions like:
sizeof((int) 1)
and changed the reduction in sizeexp() from unary to cast,
but it had the side effect of allowing things like
sizeof (int) 1
that is invalid, and having problems with things like
sizeof "hello" - 1
The commit 4a0c2ccd tried to fix this last case reverting c863f707
that moved the code to the original point. The problem is that
to avoid the ambiguity when a '(' follows a sizeof (because
it can be a typename or an expression) then the rule chain
unary
-> SIZEOF unary
-> SIZEOF postfix
-> SIZEOF primary
-> SIZEOF ( expr )
was collapsed to
unary
-> SIZEOF ( unary )
because when a ( happend after a SIZEOF token then the next token
was looked to see if it was a typename or not to decide to apply
the chain:
unary
-> SIZEOF ( typename )
And it can be seen the problem is that the collapsing was wrong
because we should have SIZEOF ( expr ) instead of SIZEOF ( unary ),
but still SIZEOF unary when no ( follows the SIZEOF token.
Diffstat:
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/cmd/cc/cc1/expr.c b/src/cmd/cc/cc1/expr.c
@@ -843,7 +843,7 @@ typeof(Node *np)
return tp;
}
-static Node *unary(void), *cast(void);
+static Node *unary(void);
static Type *
sizeexp(void)
@@ -859,7 +859,7 @@ sizeexp(void)
tp = typename();
break;
default:
- tp = typeof(unary());
+ tp = typeof(expr());
break;
}
expect(')');
@@ -903,6 +903,8 @@ postfix(Node *lp)
}
}
+static Node *cast(void);
+
static Node *
unary(void)
{