[hackers] [scc] Improve error recovery in argument parsing || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Sat, 26 Sep 2015 12:40:21 +0200 (CEST)

commit b9081437c83b589ac0618b12c555bdbc9897279f
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Sat Sep 26 12:36:59 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Sat Sep 26 12:40:06 2015 +0200

    Improve error recovery in argument parsing

diff --git a/cc1/decl.c b/cc1/decl.c
index 611873f..4dcefb1 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -116,18 +116,6 @@ arydcl(struct declarators *dp)
         push(dp, ARY, n);
 }
 
-static void
-newpar(Type *fun, Type *par)
-{
- TINT n = fun->n.elem;
-
- if (n == NR_FUNPARAM)
- error("too much parameters in function definition");
- fun->p.pars = xrealloc(fun->p.pars, ++n * sizeof(Type *));
- fun->p.pars[n-1] = par;
- fun->n.elem = n;
-}
-
 static Symbol *
 parameter(struct decl *dcl)
 {
_AT_@ -138,9 +126,6 @@ parameter(struct decl *dcl)
 
         sym->type = tp;
 
- if (n == -1)
- error("'void' must be the only parameter");
-
         switch (dcl->sclass) {
         case STATIC:
         case EXTERN:
_AT_@ -157,26 +142,30 @@ parameter(struct decl *dcl)
 
         switch (tp->op) {
         case VOID:
- if (n != 0)
- error("incorrect void parameter");
- if (dcl->sclass)
- error("void as unique parameter may not be qualified");
+ if (n != 0) {
+ errorp("incorrect void parameter");
+ return NULL;
+ }
                 funtp->n.elem = -1;
+ if (dcl->sclass)
+ errorp("void as unique parameter may not be qualified");
                 return NULL;
         case ARY:
                 tp = mktype(tp->type, PTR, 0, NULL);
                 break;
         case FTN:
- error("incorrect function type for a function parameter");
+ errorp("incorrect function type for a function parameter");
+ return NULL;
         }
 
         if (name) {
- if ((sym = install(NS_IDEN, sym)) == NULL)
- error("redefinition of parameter '%s'", name);
+ if ((sym = install(NS_IDEN, sym)) == NULL) {
+ errorp("redefinition of parameter '%s'", name);
+ return NULL;
+ }
         }
         sym->type = tp;
         sym->flags |= ISUSED; /* avoid non used warnings in prototypes */
- newpar(funtp, tp);
 
         return sym;
 }
_AT_@ -189,35 +178,62 @@ static Symbol *dodcl(int rep,
 static void
 fundcl(struct declarators *dp)
 {
- Type type;
- Symbol *syms[NR_FUNPARAM], **sp = syms;
+ Type type, *types[NR_FUNPARAM], *tp;
+ Symbol *syms[NR_FUNPARAM], *sym;
         TINT size;
- Symbol *pars = NULL;
+ Symbol *pars;
+ int toomany = 0, toovoid = 0;
 
         pushctx();
         expect('(');
         type.n.elem = 0;
- type.p.pars = NULL;
-
- if (accept(')')) {
- newpar(&type, ellipsistype);
- *sp++ = NULL;
- } else {
- do {
- if (!accept(ELLIPSIS)) {
- *sp++ = dodcl(0, parameter, NS_IDEN, &type);
- } else {
- newpar(&type, ellipsistype);
- *sp++ = NULL;
- break;
- }
- } while (accept(','));
 
- expect(')');
+ if (yytoken == ')') {
+ ++type.n.elem;
+ syms[0] = NULL;
+ types[0] = ellipsistype;
+ goto end_params;
         }
- if (type.n.elem != -1) {
+ do {
+ if (type.n.elem == -1) {
+ if (!toovoid)
+ errorp("'void' must be the only parameter");
+ toovoid = 1;
+ }
+ if (!accept(ELLIPSIS)) {
+ sym = dodcl(0, parameter, NS_IDEN, &type);
+ if (!sym)
+ continue;
+ tp = sym->type;
+ } else {
+ if (type.n.elem == 0)
+ errorp("a named argument is requiered before '...'");
+ tp = ellipsistype;
+ sym = NULL;
+ }
+ if (type.n.elem == NR_FUNPARAM) {
+ if (toomany)
+ continue;
+ errorp("too much parameters in function definition");
+ toomany = 1;
+ } else if (type.n.elem >= 0) {
+ syms[type.n.elem] = sym;
+ types[type.n.elem] = tp;
+ ++type.n.elem;
+ }
+ } while (tp != ellipsistype && accept(','));
+
+end_params:
+ expect(')');
+
+ if (type.n.elem > 0) {
                 size = type.n.elem * sizeof(Symbol *);
                 pars = memcpy(xmalloc(size), syms, size);
+ size = type.n.elem * sizeof(Type *);
+ type.p.pars = memcpy(xmalloc(size), types, size);
+ } else {
+ pars = NULL;
+ type.p.pars = NULL;
         }
         push(dp, FTN, type.n.elem, type.p.pars, pars);
 }
Received on Sat Sep 26 2015 - 12:40:21 CEST

This archive was generated by hypermail 2.3.0 : Sat Sep 26 2015 - 12:48:10 CEST