From: Zack Weinberg Date: Tue, 18 Apr 2000 06:43:41 +0000 (+0000) Subject: cppexp.c (lex): Don't assume tokens are NUL terminated. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9cc6e05fdff41972eb9674a50366bceb80389564;p=gcc.git cppexp.c (lex): Don't assume tokens are NUL terminated. * cppexp.c (lex): Don't assume tokens are NUL terminated. * cpplib.c (do_include, do_import, do_include_next, read_line_number, detect_if_not_defined): Likewise. * cpphash.c (collect_expansion): Likewise. (special_symbol, _cpp_macroexpand): Check return from cpp_file_buffer. * cpphash.h (CPP_NUL_TERMINATE, CPP_NUL_TERMINATE_Q): Delete macros. Delete all uses. * gcc.dg/cpp-mi.c: Add two more test cases. * gcc.dg/cpp-mind.h, gcc.dg/cpp-mindp.h: New files. From-SVN: r33223 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 326f168dc22..0f629e914b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2000-04-17 Zack Weinberg + + * cppexp.c (lex): Don't assume tokens are NUL terminated. + * cpplib.c (do_include, do_import, do_include_next, + read_line_number, detect_if_not_defined): Likewise. + * cpphash.c (collect_expansion): Likewise. + (special_symbol, _cpp_macroexpand): Check return from + cpp_file_buffer. + * cpphash.h (CPP_NUL_TERMINATE, CPP_NUL_TERMINATE_Q): Delete + macros. Delete all uses. + + * gcc.dg/cpp-mi.c: Add two more test cases. + * gcc.dg/cpp-mind.h, gcc.dg/cpp-mindp.h: New files. + 2000-04-17 Richard Henderson * bb-reorder.c (fixup_reorder_chain): Don't look up new block again. diff --git a/gcc/cppexp.c b/gcc/cppexp.c index 46757c581e9..237b8e686a0 100644 --- a/gcc/cppexp.c +++ b/gcc/cppexp.c @@ -444,7 +444,7 @@ lex (pfile, skip_evaluation) return parse_charconst (pfile, tok_start, tok_end); case CPP_NAME: - if (!strcmp (tok_start, "defined")) + if (!strncmp (tok_start, "defined", 7)) return parse_defined (pfile); op.op = INT; diff --git a/gcc/cpphash.c b/gcc/cpphash.c index bead2140c06..bb13dda4132 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -401,7 +401,7 @@ collect_expansion (pfile, arglist) case CPP_NAME: for (i = 0; i < argc; i++) if (!strncmp (tok, argv[i].name, argv[i].len) - && ! is_idchar (tok[argv[i].len])) + && tok + argv[i].len == CPP_PWRITTEN (pfile)) goto addref; /* fall through */ @@ -517,7 +517,6 @@ collect_expansion (pfile, arglist) while (here > last && is_hspace (pfile->token_buffer [here-1])) here--; CPP_SET_WRITTEN (pfile, here); - CPP_NUL_TERMINATE (pfile); len = CPP_WRITTEN (pfile) - start + 1; /* space for no-concat markers at either end */ exp = (U_CHAR *) xmalloc (len + 4); @@ -834,7 +833,6 @@ _cpp_quote_string (pfile, src) case '\0': CPP_PUTC_Q (pfile, '\"'); - CPP_NUL_TERMINATE_Q (pfile); return; } } @@ -851,7 +849,6 @@ special_symbol (hp, pfile) cpp_reader *pfile; { const char *buf; - int len; cpp_buffer *ip; switch (hp->type) @@ -859,6 +856,11 @@ special_symbol (hp, pfile) case T_FILE: case T_BASE_FILE: ip = cpp_file_buffer (pfile); + if (ip == NULL) + { + CPP_PUTS (pfile, "\"\"", 2); + return; + } if (hp->type == T_BASE_FILE) while (CPP_PREV_BUFFER (ip) != NULL) ip = CPP_PREV_BUFFER (ip); @@ -870,10 +872,13 @@ special_symbol (hp, pfile) case T_INCLUDE_LEVEL: { - int true_indepth = 1; + int true_indepth = 0; ip = cpp_file_buffer (pfile); - while ((ip = CPP_PREV_BUFFER (ip)) != NULL) - true_indepth++; + while (ip) + { + true_indepth++; + ip = CPP_PREV_BUFFER (ip); + } CPP_RESERVE (pfile, 10); sprintf (CPP_PWRITTEN (pfile), "%d", true_indepth); @@ -884,11 +889,10 @@ special_symbol (hp, pfile) case T_STDC: #ifdef STDC_0_IN_SYSTEM_HEADERS ip = cpp_file_buffer (pfile); - if (ip->system_header_p && !cpp_defined (pfile, DSC("__STRICT_ANSI__"))) + if (ip && ip->system_header_p + && !cpp_defined (pfile, DSC("__STRICT_ANSI__"))) { - CPP_RESERVE (pfile, 2); - CPP_PUTC_Q (pfile, '0'); - CPP_NUL_TERMINATE_Q (pfile); + CPP_PUTC (pfile, '0'); return; } #endif @@ -902,14 +906,16 @@ special_symbol (hp, pfile) if (*buf == '\0') buf = "\r "; - len = strlen (buf); - CPP_RESERVE (pfile, len + 1); - CPP_PUTS_Q (pfile, buf, len); - CPP_NUL_TERMINATE_Q (pfile); + CPP_PUTS (pfile, buf, strlen (buf)); return; case T_SPECLINE: ip = cpp_file_buffer (pfile); + if (ip == NULL) + { + CPP_PUTC (pfile, '0'); + return; + } CPP_RESERVE (pfile, 10); sprintf (CPP_PWRITTEN (pfile), "%u", CPP_BUF_LINE (ip)); CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile))); @@ -946,9 +952,7 @@ special_symbol (hp, pfile) case T_POISON: cpp_error (pfile, "attempt to use poisoned `%s'.", hp->name); - CPP_RESERVE (pfile, 1); - CPP_PUTC_Q (pfile, '0'); - CPP_NUL_TERMINATE_Q (pfile); + CPP_PUTC (pfile, '0'); break; default: @@ -983,8 +987,13 @@ _cpp_macroexpand (pfile, hp) register int i; ip = cpp_file_buffer (pfile); - start_line = CPP_BUF_LINE (ip); - start_column = CPP_BUF_COL (ip); + if (ip) + { + start_line = CPP_BUF_LINE (ip); + start_column = CPP_BUF_COL (ip); + } + else + start_line = start_column = 0; /* Check for and handle special symbols. */ if (hp->type != T_MACRO) @@ -1688,7 +1697,6 @@ _cpp_dump_definition (pfile, sym, len, defn) } if (CPP_BUFFER (pfile) == 0 || ! pfile->done_initializing) CPP_PUTC (pfile, '\n'); - CPP_NUL_TERMINATE (pfile); } /* Dump out the hash table. */ diff --git a/gcc/cpphash.h b/gcc/cpphash.h index b8f3ba9381b..90fff6496ce 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -219,9 +219,6 @@ extern unsigned char _cpp_IStable[256]; #define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH)) /* Append character CH to PFILE's output buffer. Make space if need be. */ #define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH)) -/* Make sure PFILE->limit is followed by '\0'. */ -#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0) -#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0) /* Advance the current line by one. */ #define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\ diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 6507e3307a7..1340b9c0b21 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -277,7 +277,6 @@ _cpp_expand_to_buffer (pfile, buf, length) break; } } - CPP_NUL_TERMINATE (pfile); } /* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output. @@ -630,7 +629,6 @@ _cpp_parse_name (pfile, c) if (c == EOF) break; } - CPP_NUL_TERMINATE_Q (pfile); return; } @@ -1124,7 +1122,6 @@ _cpp_lex_token (pfile) FORWARD(1); c2= c; } - CPP_NUL_TERMINATE_Q (pfile); return CPP_NUMBER; case 'b': case 'c': case 'd': case 'h': case 'o': case 'B': case 'C': case 'D': case 'H': case 'O': @@ -1147,14 +1144,12 @@ _cpp_lex_token (pfile) { CPP_RESERVE (pfile, 2); CPP_PUTC_Q (pfile, c); - CPP_NUL_TERMINATE_Q (pfile); return CPP_STRING; } else { FORWARD(-1); chill_number_eof: - CPP_NUL_TERMINATE (pfile); return CPP_NUMBER; } } diff --git a/gcc/cpplib.c b/gcc/cpplib.c index 98bd9335c90..44cc18942c5 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -505,9 +505,6 @@ parse_include (pfile, name) return 0; } - CPP_NUL_TERMINATE (pfile); - CPP_ADJUST_WRITTEN (pfile, 1); - if (_cpp_get_directive_token (pfile) != CPP_VSPACE) { cpp_error (pfile, "junk at end of `#%s'", name); @@ -533,7 +530,8 @@ do_include (pfile) if (len == 0) return 0; token = alloca (len + 1); - strcpy (token, CPP_PWRITTEN (pfile)); + memcpy (token, CPP_PWRITTEN (pfile), len); + token[len] = '\0'; if (CPP_OPTION (pfile, dump_includes)) pass_thru_directive (token, len, pfile, T_INCLUDE); @@ -561,7 +559,8 @@ do_import (pfile) if (len == 0) return 0; token = alloca (len + 1); - strcpy (token, CPP_PWRITTEN (pfile)); + memcpy (token, CPP_PWRITTEN (pfile), len); + token[len] = '\0'; if (CPP_OPTION (pfile, dump_includes)) pass_thru_directive (token, len, pfile, T_IMPORT); @@ -582,7 +581,8 @@ do_include_next (pfile) if (len == 0) return 0; token = alloca (len + 1); - strcpy (token, CPP_PWRITTEN (pfile)); + memcpy (token, CPP_PWRITTEN (pfile), len); + token[len] = '\0'; if (CPP_OPTION (pfile, dump_includes)) pass_thru_directive (token, len, pfile, T_INCLUDE_NEXT); @@ -616,18 +616,20 @@ read_line_number (pfile, num) long save_written = CPP_WRITTEN (pfile); U_CHAR *p; enum cpp_ttype token = _cpp_get_directive_token (pfile); - CPP_SET_WRITTEN (pfile, save_written); p = pfile->token_buffer + save_written; - if (token == CPP_NUMBER && *p >= '1' && *p <= '4' && p[1] == '\0') + if (token == CPP_NUMBER && p + 1 == CPP_PWRITTEN (pfile) + && p[0] >= '1' && p[0] <= '4') { *num = p[0] - '0'; + CPP_SET_WRITTEN (pfile, save_written); return 1; } else { if (token != CPP_VSPACE && token != CPP_EOF) cpp_error (pfile, "invalid format `#line' command"); + CPP_SET_WRITTEN (pfile, save_written); return 0; } } @@ -654,6 +656,7 @@ do_line (pfile) goto bad_line_directive; } + CPP_PUTC (pfile, '\0'); /* not terminated for us */ new_lineno = strtoul (pfile->token_buffer + old_written, &x, 10); if (x[0] != '\0') { @@ -1066,71 +1069,72 @@ do_sccs (pfile) `#if ! defined SYMBOL', then SYMBOL is a possible controlling macro for inclusion of this file. (See redundant_include_p in cppfiles.c for an explanation of controlling macros.) If so, return a - malloc'd copy of SYMBOL. Otherwise, return NULL. */ + malloced copy of SYMBOL. Otherwise, return NULL. */ static U_CHAR * detect_if_not_defined (pfile) cpp_reader *pfile; { U_CHAR *control_macro = 0; + enum cpp_ttype token; + unsigned int base_offset; + unsigned int token_offset; + unsigned int need_rparen = 0; + unsigned int token_len; - if (pfile->only_seen_white == 2) - { - U_CHAR *ident; - enum cpp_ttype token; - int base_offset; - int token_offset; - int need_rparen = 0; - - /* Save state required for restore. */ - pfile->no_macro_expand++; - CPP_SET_MARK (pfile); - base_offset = CPP_WRITTEN (pfile); - - /* Look for `!', */ - if (_cpp_get_directive_token (pfile) != CPP_OTHER - || CPP_WRITTEN (pfile) != (size_t) base_offset + 1 - || CPP_PWRITTEN (pfile)[-1] != '!') - goto restore; - - /* ...then `defined', */ - token_offset = CPP_WRITTEN (pfile); - token = _cpp_get_directive_token (pfile); - if (token != CPP_NAME) - goto restore; - ident = pfile->token_buffer + token_offset; - CPP_NUL_TERMINATE (pfile); - if (strcmp (ident, "defined")) - goto restore; + if (pfile->only_seen_white != 2) + return NULL; + + /* Save state required for restore. */ + pfile->no_macro_expand++; + CPP_SET_MARK (pfile); + base_offset = CPP_WRITTEN (pfile); + + /* Look for `!', */ + if (_cpp_get_directive_token (pfile) != CPP_OTHER + || CPP_WRITTEN (pfile) != (size_t) base_offset + 1 + || CPP_PWRITTEN (pfile)[-1] != '!') + goto restore; + + /* ...then `defined', */ + token_offset = CPP_WRITTEN (pfile); + token = _cpp_get_directive_token (pfile); + if (token != CPP_NAME) + goto restore; + if (strncmp (pfile->token_buffer + token_offset, "defined", 7)) + goto restore; - /* ...then an optional '(' and the name, */ + /* ...then an optional '(' and the name, */ + token_offset = CPP_WRITTEN (pfile); + token = _cpp_get_directive_token (pfile); + if (token == CPP_LPAREN) + { token_offset = CPP_WRITTEN (pfile); + need_rparen = 1; token = _cpp_get_directive_token (pfile); - if (token == CPP_LPAREN) - { - token_offset = CPP_WRITTEN (pfile); - token = _cpp_get_directive_token (pfile); - if (token != CPP_NAME) - goto restore; - need_rparen = 1; - } - else if (token != CPP_NAME) - goto restore; - - ident = pfile->token_buffer + token_offset; - CPP_NUL_TERMINATE (pfile); - - /* ...then the ')', if necessary, */ - if ((!need_rparen || _cpp_get_directive_token (pfile) == CPP_RPAREN) - /* ...and make sure there's nothing else on the line. */ - && _cpp_get_directive_token (pfile) == CPP_VSPACE) - control_macro = (U_CHAR *) xstrdup (ident); - - restore: - CPP_SET_WRITTEN (pfile, base_offset); - pfile->no_macro_expand--; - CPP_GOTO_MARK (pfile); } + if (token != CPP_NAME) + goto restore; + + token_len = CPP_WRITTEN (pfile) - token_offset; + + /* ...then the ')', if necessary, */ + if (need_rparen && _cpp_get_directive_token (pfile) != CPP_RPAREN) + goto restore; + + /* ...and make sure there's nothing else on the line. */ + if (_cpp_get_directive_token (pfile) != CPP_VSPACE) + goto restore; + + /* We have a legitimate controlling macro for this header. */ + control_macro = (U_CHAR *) xmalloc (token_len + 1); + memcpy (control_macro, pfile->token_buffer + token_offset, token_len); + control_macro[token_len] = '\0'; + + restore: + CPP_SET_WRITTEN (pfile, base_offset); + pfile->no_macro_expand--; + CPP_GOTO_MARK (pfile); return control_macro; } @@ -1218,8 +1222,7 @@ parse_ifdef (pfile, name) else if (token == CPP_NAME) { defined = cpp_defined (pfile, ident, len); - CPP_NUL_TERMINATE (pfile); - CPP_ADJUST_WRITTEN (pfile, 1); + CPP_PUTC (pfile, '\0'); /* so it can be copied with xstrdup */ } else { diff --git a/gcc/testsuite/gcc.dg/cpp-mi.c b/gcc/testsuite/gcc.dg/cpp-mi.c index 1fb62788925..a05b279558b 100644 --- a/gcc/testsuite/gcc.dg/cpp-mi.c +++ b/gcc/testsuite/gcc.dg/cpp-mi.c @@ -1,10 +1,6 @@ /* Test "ignore redundant include" facility. - This doesn't test for the case where the file is opened, and then ignored - (the file shouldn't have even been opened). That would require tracing - system calls. It could be done on some systems however. */ - -/* We have to test two cases: C comments at the top and C++ comments - at the top. */ + We must test with C and C++ comments outside the guard conditional; + also, we test guarding with #ifndef and #if !defined. */ /* { dg-do preprocess } { dg-options "" } */ @@ -15,16 +11,24 @@ #include "cpp-micc.h" #include "cpp-micc.h" -main () +#include "cpp-mind.h" +#include "cpp-mind.h" + +#include "cpp-mindp.h" +#include "cpp-mindp.h" + +int +main (void) { + return a + b + c + d; } /* { dg-final { if ![file exists cpp-mi.i] { return } } } - { dg-final { set tmp [grep cpp-mi.i cpp-micc? line] } } + { dg-final { set tmp [grep cpp-mi.i {cpp-mi.*\.h} line] } } { dg-final { # send_user "$tmp\n" } } - { dg-final { if [regexp "^{\[0-9\]+ cpp-mic} {\[0-9\]+ cpp-micc}$" $tmp] \{ } } + { dg-final { if [regexp "^{\[0-9\]+ cpp-mic\.h} {\[0-9\]+ cpp-micc\.h} {\[0-9\]+ cpp-mind\.h} {\[0-9\]+ cpp-mindp\.h}$" $tmp] \{ } } { dg-final { pass "cpp-mi.c: redundant include check" } } { dg-final { \} else \{ } } { dg-final { fail "cpp-mi.c: redundant include check" } } diff --git a/gcc/testsuite/gcc.dg/cpp-mind.h b/gcc/testsuite/gcc.dg/cpp-mind.h new file mode 100644 index 00000000000..c14c1a3c661 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp-mind.h @@ -0,0 +1,8 @@ +/* Redundant include check with #if !defined. */ + +#if !defined CPP_MIND_H +#define CPP_MIND_H + +int c; + +#endif diff --git a/gcc/testsuite/gcc.dg/cpp-mindp.h b/gcc/testsuite/gcc.dg/cpp-mindp.h new file mode 100644 index 00000000000..b84202c6d33 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp-mindp.h @@ -0,0 +1,7 @@ +#if !defined ( CPP_MINDP_H) +#define CPP_MINDP_H + +/* Redundant include check with #if !defined and parentheses. */ +int d; + +#endif