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
This commit is contained in:
Zack Weinberg 2000-04-18 06:43:41 +00:00 committed by Zack Weinberg
parent d1bfc5ad46
commit 9cc6e05fdf
9 changed files with 139 additions and 103 deletions

View File

@ -1,3 +1,17 @@
2000-04-17 Zack Weinberg <zack@wolery.cumb.org>
* 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 <rth@cygnus.com>
* bb-reorder.c (fixup_reorder_chain): Don't look up new block again.

View File

@ -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;

View File

@ -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. */

View File

@ -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++,\

View File

@ -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;
}
}

View File

@ -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)
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, */
token_offset = CPP_WRITTEN (pfile);
token = _cpp_get_directive_token (pfile);
if (token == CPP_LPAREN)
{
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);
need_rparen = 1;
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;
/* ...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);
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
{

View File

@ -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" } }

View File

@ -0,0 +1,8 @@
/* Redundant include check with #if !defined. */
#if !defined CPP_MIND_H
#define CPP_MIND_H
int c;
#endif

View File

@ -0,0 +1,7 @@
#if !defined ( CPP_MINDP_H)
#define CPP_MINDP_H
/* Redundant include check with #if !defined and parentheses. */
int d;
#endif