ref: 878d46d965b83832a939cc46707aa6f3b7e5d30e
parent: 912280612a54370fb154224164cccf24b95d1129
parent: 6e9d1522e50e81ab34916a0cf02fd838db7771c8
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Jun 22 14:32:58 EDT 2022
Merge remote-tracking branch 'origin/master'
--- a/src/cmd/cc/cc1/cc1.h
+++ b/src/cmd/cc/cc1/cc1.h
@@ -114,7 +114,8 @@
enum {
NLVAL = 1 << 0,
NCONST = 1 << 1,
- NEFFECT = 1 << 2
+ NEFFECT = 1 << 2,
+ NDECAY = 1 << 3,
};
/* lexer mode, compiler or preprocessor directive */
--- a/src/cmd/cc/cc1/code.c
+++ b/src/cmd/cc/cc1/code.c
@@ -578,5 +578,6 @@
sym = newsym(NS_IDEN, NULL);
sym->type = sizettype;
sym->u.i = tp->size;
+ DBG("EXPR sizeof %llu", sym->u.i);
return constnode(sym);
}
--- a/src/cmd/cc/cc1/expr.c
+++ b/src/cmd/cc/cc1/expr.c
@@ -8,8 +8,6 @@
#define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np)
-static Node *xexpr(void), *xassign(void);
-
int
cmpnode(Node *np, TUINT val)
{
@@ -194,6 +192,7 @@
switch (tp->op) {
case ARY:
+ DBG("EXPR decay ary");
tp = tp->type;
if (np->op == OPTR) {
new = np->left;
@@ -201,14 +200,20 @@
new->type = mktype(tp, PTR, 0, NULL);
return new;
}
+ break;
case FTN:
- new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);
- if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
- new->flags |= NCONST;
- return new;
+ DBG("EXPR decay function");
+ break;
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 *
@@ -535,24 +540,33 @@
address(int op, Node *np)
{
Node *new;
+ Type *tp;
+ Symbol *sym = np->sym;
+ if ((np->flags & NDECAY) != 0) {
+ new = np->left;
+ free(np);
+ np = new;
+ }
+ tp = np->type;
+
/*
* ansi c accepts & applied to a function name, and it generates
* a function pointer
*/
if (np->op == OSYM) {
- if (np->type->op == FTN)
+ if (tp->op == FTN)
return decay(np);
- if (np->type->op == ARY)
+ if (tp->op == ARY)
goto dont_check_lvalue;
}
chklvalue(np);
dont_check_lvalue:
- if (np->sym && (np->sym->flags & SREGISTER))
+ if (sym && (sym->flags & SREGISTER))
errorp("address of register variable '%s' requested", yytext);
- new = node(op, mktype(np->type, PTR, 0, NULL), np, NULL);
- if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
+ new = node(op, mktype(tp, PTR, 0, NULL), np, NULL);
+ if (sym && sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
new->flags |= NCONST;
return new;
}
@@ -629,7 +643,7 @@
break;
case '(':
next();
- np = xexpr();
+ np = expr();
expect(')');
/* do not call to next */
@@ -685,7 +699,7 @@
toomany = 0;
do {
- arg = xassign();
+ arg = assign();
argtype = *targs;
if (argtype == ellipsistype) {
n = 0;
@@ -725,26 +739,34 @@
return node(op, rettype, np, par);
}
-static Node *unary(int);
-
static Type *
typeof(Node *np)
{
+ Node *new;
Type *tp;
if (np == NULL)
unexpected();
+ if ((np->flags & NDECAY) != 0) {
+ new = np->left;
+ free(np);
+ np = new;
+ }
tp = np->type;
freetree(np);
return tp;
}
+static Node *cast(void);
+
static Type *
sizeexp(void)
{
Type *tp;
- expect('(');
+ if (!accept('('))
+ return typeof(cast());
+
switch (yytoken) {
case TYPE:
case TYPEIDEN:
@@ -751,10 +773,11 @@
tp = typename();
break;
default:
- tp = typeof(unary(0));
+ tp = typeof(cast());
break;
}
expect(')');
+
return tp;
}
@@ -768,7 +791,7 @@
switch (yytoken) {
case '[':
next();
- rp = xexpr();
+ rp = expr();
expect(']');
lp = array(decay(lp), rp);
break;
@@ -794,10 +817,8 @@
}
}
-static Node *cast(int);
-
static Node *
-unary(int needdecay)
+unary(void)
{
Node *(*fun)(int, Node *), *np;
int op;
@@ -812,7 +833,7 @@
case '*': op = OPTR; fun = content; break;
case SIZEOF:
next();
- tp = (yytoken == '(') ? sizeexp() : typeof(unary(0));
+ tp = sizeexp();
if (!(tp->prop & TDEFINED))
errorp("sizeof applied to an incomplete type");
return sizeofnode(tp);
@@ -820,26 +841,24 @@
case DEC:
op = (yytoken == INC) ? OA_ADD : OA_SUB;
next();
- np = incdec(unary(1), op);
- goto chk_decay;
+ np = incdec(unary(), op);
+ goto decay;
case DEFINED:
return defined();
default:
np = postfix(primary());
- goto chk_decay;
+ goto decay;
}
next();
- np = (*fun)(op, cast(op != OADDR));
+ np = (*fun)(op, cast());
-chk_decay:
- if (needdecay)
- np = decay(np);
- return np;
+decay:
+ return decay(np);
}
static Node *
-cast(int needdecay)
+cast(void)
{
Node *tmp, *np;
Type *tp;
@@ -846,7 +865,7 @@
static int nested;
if (!accept('('))
- return unary(needdecay);
+ return unary();
switch (yytoken) {
case TQUALIFIER:
@@ -862,7 +881,7 @@
case ARY:
error("cast specifies an array type");
default:
- tmp = cast(needdecay);
+ tmp = cast();
if ((np = convert(tmp, tp, 1)) == NULL)
error("bad type conversion requested");
np->flags &= ~NLVAL;
@@ -872,7 +891,7 @@
if (nested == NR_SUBEXPR)
error("too many expressions nested by parentheses");
++nested;
- np = xexpr();
+ np = expr();
--nested;
expect(')');
np = postfix(np);
@@ -888,7 +907,7 @@
Node *np, *(*fun)(int, Node *, Node *);
int op;
- np = cast(1);
+ np = cast();
for (;;) {
switch (yytoken) {
case '*': op = OMUL; fun = arithmetic; break;
@@ -897,7 +916,7 @@
default: return np;
}
next();
- np = (*fun)(op, np, cast(1));
+ np = (*fun)(op, np, cast());
}
}
@@ -1040,7 +1059,7 @@
Node *ifyes, *ifno, *np;
cond = exp2cond(cond, 0);
- ifyes = xexpr();
+ ifyes = expr();
expect(':');
ifno = ternary();
np = chkternary(ifyes, ifno);
@@ -1049,8 +1068,8 @@
return cond;
}
-static Node *
-xassign(void)
+Node *
+assign(void)
{
Node *np, *(*fun)(int , Node *, Node *);
int op;
@@ -1069,7 +1088,7 @@
case AND_EQ: op = OA_AND; fun = integerop; break;
case XOR_EQ: op = OA_XOR; fun = integerop; break;
case OR_EQ: op = OA_OR; fun = integerop; break;
- default: return np;
+ default: return simplify(np);
}
chklvalue(np);
np->flags |= NEFFECT;
@@ -1078,23 +1097,21 @@
}
}
-static Node *
-xexpr(void)
+Node *
+expr(void)
{
Node *lp, *rp;
- lp = xassign();
- while (accept(',')) {
- rp = xassign();
+ lp = assign();
+ if (!accept(','))
+ return lp;
+
+ do {
+ rp = assign();
lp = node(OCOMMA, rp->type, lp, rp);
- }
- return lp;
-}
+ } while (accept(','));
-Node *
-assign(void)
-{
- return simplify(xassign());
+ return simplify(lp);
}
Node *
@@ -1113,17 +1130,11 @@
}
Node *
-expr(void)
-{
- return simplify(xexpr());
-}
-
-Node *
condexpr(int neg)
{
Node *np;
- np = exp2cond(xexpr(), neg);
+ np = exp2cond(expr(), neg);
if (np->flags & NCONST)
warn("conditional expression is constant");
return simplify(np);
--- a/src/cmd/cc/cc1/stmt.c
+++ b/src/cmd/cc/cc1/stmt.c
@@ -156,9 +156,12 @@
emit(OBLOOP, NULL);
emit(OLABEL, begin);
+
stmt(lbreak, lcont, lswitch);
expect(WHILE);
np = condition(NONEGATE);
+ expect(';');
+
emit(OLABEL, lcont);
emit(OBRANCH, begin);
emit(OEXPR, np);
--- /dev/null
+++ b/tests/cc/execute/0209-dowhile.c
@@ -1,0 +1,9 @@
+int
+main(void)
+{
+ if (1)
+ do { } while(0);
+ else
+ do { } while(0);
+ return 0;
+}
--- a/tests/cc/execute/0209-flexible.c
+++ /dev/null
@@ -1,17 +1,0 @@
-struct str {
- int a;
- char v[];
-};
-
-int
-main(void)
-{
- struct str *p;
- int ary[20];
-
- p = (struct str *) ary;
- p->a = 2;
- p->v[0] = 1;
-
- return !(p->a + p->v[0] == 3);
-}
--- /dev/null
+++ b/tests/cc/execute/0210-flexible.c
@@ -1,0 +1,17 @@
+struct str {
+ int a;
+ char v[];
+};
+
+int
+main(void)
+{
+ struct str *p;
+ int ary[20];
+
+ p = (struct str *) ary;
+ p->a = 2;
+ p->v[0] = 1;
+
+ return !(p->a + p->v[0] == 3);
+}
--- a/tests/cc/execute/scc-tests.lst
+++ b/tests/cc/execute/scc-tests.lst
@@ -169,7 +169,7 @@
0176-macro.c
0177-literal.c [TODO]
0178-include.c
-0179-sizeof.c [TODO]
+0179-sizeof.c
0180-incomplete.c
0181-stringize.c
0182-voidcast.c
@@ -199,4 +199,5 @@
0206-initializer.c
0207-structcb.c
0208-sizeof.c
-0209-flexible.c
+0209-dowhile.c
+0210-flexible.c