commit 49f35dc9bb53bafb4fced17fc3d62754620a7792
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Mon Jan 30 15:52:29 2017 +0100
Commit:     Quentin Rameau <[email protected]>
CommitDate: Mon Jan 30 16:07:06 2017 +0100

    [cc1] Use LOC variables for input
    
    It is a bad idea to use the values stored directly in input structures,
    because input structures disappear before the errors are printed, so it
    means that we can try to access through a NULL pointer.
    
    Small fix in newline() and addinput() clarification by quinq.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index 1a9e3c5..e9eac6f 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -352,8 +352,8 @@ struct yystype {
 
 struct input {
        char flags;
-       unsigned short nline;
-       char *fname;
+       unsigned lineno;
+       char *filenam;
        FILE *fp;
        Symbol *hide;
        char *line, *begin, *p;
@@ -406,6 +406,7 @@ extern int addinput(char *fname, Symbol *hide, char 
*buffer);
 extern void delinput(void);
 extern void setsafe(int type);
 extern void ilex(void);
+extern int setloc(char *fname, unsigned line);
 #define accept(t) ((yytoken == (t)) ? next() : 0)
 
 /* code.c */
@@ -458,6 +459,8 @@ extern int onlycpp, onlyheader;
 extern unsigned curctx;
 extern Symbol *curfun, *zero, *one;
 extern char *infile, *outfile;
+unsigned lineno;
+char filenam[FILENAME_MAX];
 
 extern Type *voidtype, *pvoidtype, *booltype,
             *uchartype,   *chartype, *schartype,
diff --git a/cc1/cpp.c b/cc1/cpp.c
index 30b59ea..bd65816 100644
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -34,8 +34,8 @@ defdefine(char *macro, char *val, char *source)
        def = xmalloc(strlen(fmt) + strlen(macro) + strlen(val));
 
        sprintf(def, fmt, macro, val);
+       lineno = ++ncmdlines;
        addinput(source, &dummy, def);
-       input->nline = ++ncmdlines;
        cpp();
        delinput();
 }
@@ -254,11 +254,11 @@ expand(char *begin, Symbol *sym)
 
        macroname = sym->name;
        if (sym == symfile) {
-               elen = sprintf(buffer, "\"%s\" ", input->fname);
+               elen = sprintf(buffer, "\"%s\" ", filenam);
                goto substitute;
        }
        if (sym == symline) {
-               elen = sprintf(buffer, "%d ", input->nline);
+               elen = sprintf(buffer, "%d ", lineno);
                goto substitute;
        }
        if (!s)
@@ -275,7 +275,7 @@ expand(char *begin, Symbol *sym)
 substitute:
        DBG("MACRO '%s' expanded to :'%s'", macroname, buffer);
        buffer[elen] = '\0';
-       addinput(input->fname, sym, xstrdup(buffer));
+       addinput(filenam, sym, xstrdup(buffer));
 
        return 1;
 }
@@ -448,7 +448,7 @@ includefile(char *dir, char *file, size_t filelen)
 static char *
 cwd(char *buf)
 {
-       char *p, *s = input->fname;
+       char *p, *s = filenam;
        size_t len;
 
        if ((p = strrchr(s, '/')) == NULL)
@@ -538,7 +538,7 @@ static void
 line(void)
 {
        long n;
-       char *endp;
+       char *endp, *fname;
 
        if (cppoff)
                return;
@@ -552,20 +552,18 @@ line(void)
        }
 
        next();
-       if (yytoken == EOFTOK)
-               goto set_line;
-
-       if (*yytext != '\"' || yylen == 1) {
-               cpperror("second parameter of #line is not a valid filename");
-               return;
+       if (yytoken == '\n') {
+               fname = NULL;
+       } else {
+               if (*yytext != '\"' || yylen == 1) {
+                       cpperror("second parameter of #line is not a valid 
filename");
+                       return;
+               }
+               fname = yylval.sym->u.s;
        }
-
-       free(input->fname);
-       input->fname = xstrdup(yylval.sym->u.s);
-       next();
-
-set_line:
-       input->nline = n - 1;
+       setloc(fname, n - 1);
+       if (yytoken != '\n')
+               next();
 }
 
 static void
diff --git a/cc1/error.c b/cc1/error.c
index 785e2ed..e60b785 100644
--- a/cc1/error.c
+++ b/cc1/error.c
@@ -18,7 +18,7 @@ warn_error(int flag, char *fmt, va_list va)
        if (flag == 0)
                return;
        fprintf(stderr, "%s:%u: %s: ",
-              input->fname, input->nline,
+              filenam, lineno,
               (flag < 0) ? "error" : "warning");
        vfprintf(stderr, fmt, va);
        putc('\n', stderr);
diff --git a/cc1/lex.c b/cc1/lex.c
index dc17712..66612d6 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -18,6 +18,8 @@ struct yystype yylval;
 char yytext[STRINGSIZ+3];
 unsigned short yylen;
 int lexmode = CCMODE;
+unsigned lineno;
+char filenam[FILENAME_MAX];
 
 int namespace = NS_IDEN;
 static int safe;
@@ -69,17 +71,31 @@ ilex(void)
 }
 
 int
+setloc(char *fname, unsigned line)
+{
+       size_t len;
+
+       if ((len = strlen(fname)) >= FILENAME_MAX)
+               die("file name too long: '%s'", fname);
+       memcpy(filenam, fname, len);
+       filenam[len] = '\0';
+
+       free(input->filenam);
+       input->filenam = xstrdup(fname);
+       lineno = input->lineno = line;
+       return 1;
+}
+
+int
 addinput(char *fname, Symbol *hide, char *buffer)
 {
        FILE *fp;
-       unsigned flags, nline = 0;
-       Input *ip;
+       unsigned flags;
+       Input *newip, *curip = input;
 
        if (hide) {
                /* this is a macro expansion */
                fp = NULL;
-               if (input)
-                       nline = input->nline;
                if (hide->hide == UCHAR_MAX)
                        die("Too many macro expansions");
                ++hide->hide;
@@ -87,9 +103,9 @@ addinput(char *fname, Symbol *hide, char *buffer)
        } else  if (fname) {
                /* a new file */
                if ((fp = fopen(fname, "r")) == NULL)
-                       return 0;
+                       die("Error opening '%s': %s", fname, strerror(errno));
                flags = IFILE;
-               if (input && onlyheader)
+               if (curip && onlyheader)
                        printf("%s: %s\n", infile, fname);
        } else {
                /* reading from stdin */
@@ -98,23 +114,26 @@ addinput(char *fname, Symbol *hide, char *buffer)
                flags = ISTDIN;
        }
 
-       ip = xmalloc(sizeof(*ip));
+       newip = xmalloc(sizeof(*newip));
 
        if (!buffer) {
                buffer = xmalloc(INPUTSIZ);
                buffer[0] = '\0';
        }
 
-       ip->p = ip->begin = ip->line = buffer;
-       ip->fname = xstrdup(fname);
-       ip->next = input;
-       ip->fp = fp;
-       ip->hide = hide;
-       ip->nline = nline;
-       ip->flags = flags;
-       input = ip;
+       if (curip)
+               curip->lineno = lineno;
 
-       return 1;
+       newip->p = newip->begin = newip->line = buffer;
+       newip->filenam = NULL;
+       newip->lineno = 0;
+       newip->next = curip;
+       newip->fp = fp;
+       newip->hide = hide;
+       newip->flags = flags;
+       input = newip;
+
+       return setloc(fname, (curip) ? curip->lineno : newip->lineno);
 }
 
 void
@@ -127,7 +146,7 @@ delinput(void)
        case IFILE:
                if (fclose(ip->fp))
                        die("error: failed to read from input file '%s'",
-                           ip->fname);
+                           ip->filenam);
                break;
        case IMACRO:
                assert(hide->hide == 1);
@@ -135,15 +154,19 @@ delinput(void)
                break;
        }
        input = ip->next;
-       free(ip->fname);
+       free(ip->filenam);
        free(ip->line);
+       if (input) {
+               lineno = input->lineno;
+               strcpy(filenam, input->filenam);
+       }
 }
 
 static void
 newline(void)
 {
-       if (++input->nline == 0)
-               die("error: input file '%s' too long", input->fname);
+       if (++lineno == 0)
+               die("error: input file '%s' too long", filenam);
 }
 
 /*
@@ -280,15 +303,15 @@ repeat:
                char *s;
 
                putchar('\n');
-               if (strcmp(file, input->fname)) {
-                       strcpy(file, input->fname);
+               if (strcmp(file, filenam)) {
+                       strcpy(file, filenam);
                        s = "#line %u %s\n";
-               } else if (nline+1 != input->nline) {
+               } else if (nline+1 != lineno) {
                        s = "#line %u\n";
                } else {
                        s = "";
                }
-               nline = input->nline;
+               nline = lineno;
                printf(s, nline, file);
        }
        return 1;

Reply via email to