Commit 2c088b53 by Neil Booth Committed by Neil Booth

cpptrad.c (scan_out_logical_line): Check recursing only when we know we have a…

cpptrad.c (scan_out_logical_line): Check recursing only when we know we have a macro invocation in the...

	* cpptrad.c (scan_out_logical_line): Check recursing only when
	we know we have a macro invocation in the function-like case.
	Only call _cpp_handle_directive if we know we have a good
	directive, or we want to reject a bad directive.
testsuite:
	* gcc.dg/cpp/trad/argcout.c, gcc.dg/cpp/trad/assembler.S,
	gcc.dg/cpp/trad/argcout.c, gcc.dg/cpp/trad/funlike-4.c,
	gcc.dg/cpp/trad/null-drctv.c, gcc.dg/cpp/trad/recurse-1.c,
	gcc.dg/cpp/trad/recurse-2.c, gcc.dg/cpp/trad/recurse-3.c:
	New tests.
	* gcc.dg/cpp/trad/directive.c: Update.

From-SVN: r54942
parent 66443ad2
2002-06-24 Neil Booth <neil@daikokuya.co.uk>
* cpptrad.c (scan_out_logical_line): Check recursing only when
we know we have a macro invocation in the function-like case.
Only call _cpp_handle_directive if we know we have a good
directive, or we want to reject a bad directive.
2002-06-24 Alan Modra <amodra@bigpond.net.au> 2002-06-24 Alan Modra <amodra@bigpond.net.au>
* doloop.c (doloop_valid_p): Correct comment. * doloop.c (doloop_valid_p): Correct comment.
......
...@@ -579,8 +579,7 @@ scan_out_logical_line (pfile, macro) ...@@ -579,8 +579,7 @@ scan_out_logical_line (pfile, macro)
if (node->type == NT_MACRO if (node->type == NT_MACRO
/* Should we expand for ls_answer? */ /* Should we expand for ls_answer? */
&& (lex_state == ls_none || lex_state == ls_fun_open) && (lex_state == ls_none || lex_state == ls_fun_open)
&& !pfile->state.prevent_expansion && !pfile->state.prevent_expansion)
&& !recursive_macro (pfile, node))
{ {
/* Macros invalidate MI optimization. */ /* Macros invalidate MI optimization. */
pfile->mi_valid = false; pfile->mi_valid = false;
...@@ -592,7 +591,7 @@ scan_out_logical_line (pfile, macro) ...@@ -592,7 +591,7 @@ scan_out_logical_line (pfile, macro)
fmacro.line = pfile->line; fmacro.line = pfile->line;
continue; continue;
} }
else else if (!recursive_macro (pfile, node))
{ {
/* Remove the object-like macro's name from the /* Remove the object-like macro's name from the
output, and push its replacement text. */ output, and push its replacement text. */
...@@ -630,10 +629,15 @@ scan_out_logical_line (pfile, macro) ...@@ -630,10 +629,15 @@ scan_out_logical_line (pfile, macro)
paren_depth++; paren_depth++;
if (lex_state == ls_fun_open) if (lex_state == ls_fun_open)
{ {
lex_state = ls_fun_close; if (recursive_macro (pfile, fmacro.node))
paren_depth = 1; lex_state = ls_none;
out = pfile->out.base + fmacro.offset; else
fmacro.args[0] = fmacro.offset; {
lex_state = ls_fun_close;
paren_depth = 1;
out = pfile->out.base + fmacro.offset;
fmacro.args[0] = fmacro.offset;
}
} }
else if (lex_state == ls_predicate) else if (lex_state == ls_predicate)
lex_state = ls_answer; lex_state = ls_answer;
...@@ -681,15 +685,43 @@ scan_out_logical_line (pfile, macro) ...@@ -681,15 +685,43 @@ scan_out_logical_line (pfile, macro)
break; break;
case '#': case '#':
/* At start of a line it's a directive. */
if (out - 1 == pfile->out.base && !pfile->state.in_directive) if (out - 1 == pfile->out.base && !pfile->state.in_directive)
{ {
/* This is a kludge. We want to have the ISO /* A directive. With the way _cpp_handle_directive
preprocessor lex the next token. */ currently works, we only want to call it if either we
pfile->buffer->cur = cur; know the directive is OK, or we want it to fail and
if (_cpp_handle_directive (pfile, false /* indented */)) be removed from the output. If we want it to be
goto start_logical_line; passed through (the assembler case) then we must not
call _cpp_handle_directive. */
pfile->out.cur = out;
cur = skip_whitespace (pfile, cur, true /* skip_comments */);
out = pfile->out.cur;
if (is_vspace (*cur))
/* Null directive ignored. */
out = pfile->out.base;
else
{
bool do_it = false;
if (is_numstart (*cur))
do_it = true;
else if (is_idstart (*cur))
/* Check whether we know this directive, but don't
advance. */
do_it = lex_identifier (pfile, cur)->directive_index != 0;
if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM)
{
/* This is a kludge. We want to have the ISO
preprocessor lex the next token. */
pfile->buffer->cur = cur;
_cpp_handle_directive (pfile, false /* indented */);
goto start_logical_line;
}
}
} }
if (pfile->state.in_expression) if (pfile->state.in_expression)
{ {
lex_state = ls_hash; lex_state = ls_hash;
......
2002-06-24 Neil Booth <neil@daikokuya.co.uk>
* gcc.dg/cpp/trad/argcout.c, gcc.dg/cpp/trad/assembler.S,
gcc.dg/cpp/trad/argcout.c, gcc.dg/cpp/trad/funlike-4.c,
gcc.dg/cpp/trad/null-drctv.c, gcc.dg/cpp/trad/recurse-1.c,
gcc.dg/cpp/trad/recurse-2.c, gcc.dg/cpp/trad/recurse-3.c:
New tests.
* gcc.dg/cpp/trad/directive.c: Update.
2002-06-23 Andreas Jaeger <aj@suse.de> 2002-06-23 Andreas Jaeger <aj@suse.de>
* gcc.c-torture/execute/complex-6.c: New. * gcc.c-torture/execute/complex-6.c: New.
......
/* Test that we correctly complain about an invalid number of macro
arguments. */
/* { dg-do preprocess } */
#define f(x) x
#define g(x, y) x y
#define h()
f(); /* { dg-bogus "requires 1" "no arg is 1 empty arg" } */
f( ); /* { dg-bogus "macro" "1 arg to 1 param macro" } */
f(1,); /* { dg-error "passed 2" "2 args to 1 param macro" } */
f(1,2); /* { dg-error "passed 2" "2 args to 1 param macro" } */
h(); /* { dg-bogus "macro" "no arg to 1 param macro" } */
h( ); /* { dg-error "passed 1" "1 arg to 0 param macro" } */
h(1,2); /* { dg-error "passed 2" "2 args to 0 param macro" } */
g(); /* { dg-error "requires 2" "0 args to 2 param macro" } */
g( ); /* { dg-error "requires 2" "1 args to 2 param macro" } */
g( ,2); /* { dg-bogus "requires 2" "2 args to 2 param macro" } */
g(,); /* { dg-bogus "requires 2" "2 args to 2 param macro" } */
g(1,2,3); /* { dg-error "passed 3" "3 args to 2 param macro" } */
/* Regression test - in assembly language, # may have some significance
other than 'stringize macro argument' and therefore must be preserved
in the output, and should not be warned about. */
/* { dg-do preprocess } */
#define foo() mov r0, #5 /* { dg-bogus "not followed" "spurious warning" } */
entry:
foo()
/* Check we don't EOF on an unknown directive. */
#unknown directive
#error a later diagnostic /* { dg-error "diagnostic" } */
/*
{ dg-final { if ![file exists 20000510-1.i] { return } } }
{ dg-final { set tmp [grep 20000510-1.i # line] } }
{ dg-final { if {[string length $tmp] > 0} \{ } }
{ dg-final { pass "20000510-1.S: # preservation" } }
{ dg-final { \} else \{ } }
{ dg-final { fail "20000510-1.S: # preservation" } }
{ dg-final { \} } }
*/
...@@ -8,3 +8,5 @@ ...@@ -8,3 +8,5 @@
/* Directives with their #s indented are not recognized. */ /* Directives with their #s indented are not recognized. */
#if 0 /* { dg-bogus "unterminated" } */ #if 0 /* { dg-bogus "unterminated" } */
#wrong /* { dg-error "invalid" } */
/* Test that undefined names evaluate to zero, that macros after a
funlike macro are expanded, and that if it is a '(' the funlike
macro is not treated as such. */
/* { dg-do run } */
extern void abort (void);
#define f(x) x
int main ()
{
#if f(1) == f /**/ (/**/1/**/)
int x;
#endif
x = 0;
if (f
/**/ (
/**/ 0/**/
/**/)
)
abort ();
return 0;
}
/* Test that the null directive doesn't swallow the following line. */
/* { dg-do preprocess } */
#
#error OK /* { dg-error "OK" } */
/* Test for warning of and recovery from recursion in object-like
macros. */
/* { dg-do preprocess } */
#define foo foo
foo /* { dg-error "detected recursion" } */
#define bar a bar b
bar /* { dg-error "detected recursion" } */
/* Test for warning of and recovery from recursion in function-like
macros. */
/* { dg-do preprocess } */
#define foo() foo()
foo(); /* { dg-error "detected recursion" } */
#define bar() bar baz() bar
bar(); /* { dg-bogus "detected recursion" } */
#define baz() foo()
baz(); /* { dg-error "detected recursion" } */
#define a(x) x(a)
a(a); /* { dg-error "detected recursion" } */
/* Tests that macros that look recursive but are not are accepted. */
/* { dg-do preprocess } */
#define g(x) x
g(g(g(g(g(g(g)))))); /* { dg-bogus "detected recursion" } */
/* This macro gets longer with each loop, to thwart tests for
recursion based on length. */
#define f(a,b,c,d,e,f,g,h,i) a(b,c,d,e,f,g,h,i,2 3 4 5)
f(f,f,f,f,f,f,f,f,f) /* { dg-bogus "detected recursion" } */
/* The above cases should be enough, but this is taken from cccp
sources so let's try it too. */
#define foo(x,y) bar (x (y,0), y)
foo (foo, baz); /* { dg-bogus "detected recursion" } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment