commit ab74e508b10e6bdf39ae71e204bf91642257d689
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Fri Aug 7 20:28:12 2015 +0200
Commit:     Roberto E. Vargas Caballero <[email protected]>
CommitDate: Fri Aug 7 20:28:12 2015 +0200

    Fix fundcl()
    
    Fundcl() has to take the decision when it is needed the parameter
    context or not, and the only way is to check if the next token
    is a allowed one in a function definition. Ideally the
    context should be poped before calling expect(), but we know
    that after a parameter list cannot go a identifier, so it is
    not a problem.

diff --git a/cc1/decl.c b/cc1/decl.c
index 154777b..c8c96f1 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -91,34 +91,43 @@ fundcl(struct dcldata *dp)
        Type type = {.n = {.elem = -1}, .pars = NULL};
        Symbol *syms[NR_FUNPARAM], **sp;
        size_t size;
+       void *p;
 
        pushctx();
        expect('(');
 
-       if (accept(')'))
-               goto nopars;
-
-       type.n.elem = 0;
-       sp = syms;
-       do
-               *sp++ = dodcl(0, parameter, NS_IDEN, &type);
-       while (accept(','));
+       if (accept(')')) {
+               dp = queue(dp, FTN, type.n.elem, type.pars);
+       } else {
+               type.n.elem = 0;
+               sp = syms;
+               do
+                       *sp++ = dodcl(0, parameter, NS_IDEN, &type);
+               while (accept(','));
 
-       if (ahead() != '{')
-               goto nopars;
+               expect(')');
 
-       expect(')');
+               dp = queue(dp, FTN, type.n.elem, type.pars);
+               if (type.n.elem != -1) {
+                       size = type.n.elem * sizeof(Symbol *);
+                       p = memcpy(xmalloc(size), syms, size);
+                       dp = queue(dp, PARS, 0, p);
+               }
+       }
 
-       dp = queue(dp, FTN, type.n.elem, type.pars);
-       if (type.n.elem != -1) {
-               size = type.n.elem * sizeof(Symbol *);
-               dp = queue(dp, PARS, 0, memcpy(xmalloc(size), syms, size));
+       switch (yytoken) {
+       default:
+               /* This is not a function */
+               popctx();
+       case '{':
+       case TYPEIDEN:
+       case TYPE:
+       case TQUALIFIER:
+       case SCLASS:
+               /* This can be a function (K&R included) */
+               break;
        }
        return dp;
-
-nopars:
-       expect(')');
-       return queue(dp, FTN, type.n.elem, type.pars);
 }
 
 static struct dcldata *declarator0(struct dcldata *dp, unsigned ns);
@@ -457,9 +466,7 @@ internal(Symbol *sym, int sclass, Type *data)
                warn("empty declaration");
                return;
        }
-       if (sym->type->op == FTN) {
-               popctx();
-       } else {
+       if (sym->type->op != FTN) {
                if (!sclass)
                        sym->flags |= ISAUTO;
                if (accept('='))

Reply via email to