Commit c04babd9 by Jakub Jelinek

libcpp: Fix ICEs on __has_include syntax errors [PR93545]

Some of the following testcases ICE, because one of the cpp_get_token
calls in builtin_has_include reads the CPP_EOF token but the caller isn't
aware that CPP_EOF has been reached and will do another cpp_get_token.
get_token_no_padding is something that is use by the
has_attribute/has_builtin callbacks, which will first peek and will not
consume CPP_EOF (but will consume other tokens).  The !SEEN_EOL ()
check on the other side doesn't work anymore and isn't really needed,
as we don't consume the EOF.  The change adds one further error to the
pr88974.c testcase, if we wanted just one error per __has_include,
we could add some boolean whether we've emitted errors already and
only emit the first one we encounter (not implemented).

2020-02-04  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/93545
	* macro.c (cpp_get_token_no_padding): New function.
	(builtin_has_include): Use it instead of cpp_get_token.  Don't check
	SEEN_EOL.

	* c-c++-common/cpp/pr88974.c: Expect another diagnostics during error
	recovery.
	* c-c++-common/cpp/pr93545-1.c: New test.
	* c-c++-common/cpp/pr93545-2.c: New test.
	* c-c++-common/cpp/pr93545-3.c: New test.
	* c-c++-common/cpp/pr93545-4.c: New test.
parent 5bc9d2f5
2020-02-04 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/93545
* c-c++-common/cpp/pr88974.c: Expect another diagnostics during error
recovery.
* c-c++-common/cpp/pr93545-1.c: New test.
* c-c++-common/cpp/pr93545-2.c: New test.
* c-c++-common/cpp/pr93545-3.c: New test.
* c-c++-common/cpp/pr93545-4.c: New test.
2020-02-04 Iain Sandoe <iain@sandoe.co.uk> 2020-02-04 Iain Sandoe <iain@sandoe.co.uk>
* g++.dg/coroutines/coro-missing-promise.C: New test. * g++.dg/coroutines/coro-missing-promise.C: New test.
......
...@@ -3,4 +3,5 @@ ...@@ -3,4 +3,5 @@
#if __has_include (<pr88974.h) #if __has_include (<pr88974.h)
/* { dg-error "missing terminating > character" "" { target *-*-* } .-1 } */ /* { dg-error "missing terminating > character" "" { target *-*-* } .-1 } */
/* { dg-error "missing '\\\)' after .__has_include. operand" "" { target *-*-* } .-2 } */
#endif #endif
/* PR preprocessor/93545 */
/* { dg-do preprocess } */
__has_include /* { dg-error "" } */
/* PR preprocessor/93545 */
/* { dg-do preprocess } */
__has_include ( /* { dg-error "" } */
/* PR preprocessor/93545 */
/* { dg-do preprocess } */
__has_include ("foobarbaz" /* { dg-error "" } */
/* PR preprocessor/93545 */
/* { dg-do preprocess } */
__has_include () /* { dg-error "" } */
2020-02-04 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/93545
* macro.c (cpp_get_token_no_padding): New function.
(builtin_has_include): Use it instead of cpp_get_token. Don't check
SEEN_EOL.
2020-02-01 Andrew Burgess <andrew.burgess@embecosm.com> 2020-02-01 Andrew Burgess <andrew.burgess@embecosm.com>
* configure: Regenerate. * configure: Regenerate.
......
...@@ -336,6 +336,22 @@ unsigned num_expanded_macros_counter = 0; ...@@ -336,6 +336,22 @@ unsigned num_expanded_macros_counter = 0;
from macro expansion. */ from macro expansion. */
unsigned num_macro_tokens_counter = 0; unsigned num_macro_tokens_counter = 0;
/* Wrapper around cpp_get_token to skip CPP_PADDING tokens
and not consume CPP_EOF. */
static const cpp_token *
cpp_get_token_no_padding (cpp_reader *pfile)
{
for (;;)
{
const cpp_token *ret = cpp_peek_token (pfile, 0);
if (ret->type == CPP_EOF)
return ret;
ret = cpp_get_token (pfile);
if (ret->type != CPP_PADDING)
return ret;
}
}
/* Handle meeting "__has_include" builtin macro. */ /* Handle meeting "__has_include" builtin macro. */
static int static int
...@@ -344,10 +360,10 @@ builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next) ...@@ -344,10 +360,10 @@ builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next)
int result = 0; int result = 0;
pfile->state.angled_headers = true; pfile->state.angled_headers = true;
const cpp_token *token = cpp_get_token (pfile); const cpp_token *token = cpp_get_token_no_padding (pfile);
bool paren = token->type == CPP_OPEN_PAREN; bool paren = token->type == CPP_OPEN_PAREN;
if (paren) if (paren)
token = cpp_get_token (pfile); token = cpp_get_token_no_padding (pfile);
else else
cpp_error (pfile, CPP_DL_ERROR, cpp_error (pfile, CPP_DL_ERROR,
"missing '(' before \"%s\" operand", NODE_NAME (op)); "missing '(' before \"%s\" operand", NODE_NAME (op));
...@@ -379,7 +395,8 @@ builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next) ...@@ -379,7 +395,8 @@ builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next)
XDELETEVEC (fname); XDELETEVEC (fname);
} }
if (paren && !SEEN_EOL () && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN) if (paren
&& cpp_get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN)
cpp_error (pfile, CPP_DL_ERROR, cpp_error (pfile, CPP_DL_ERROR,
"missing ')' after \"%s\" operand", NODE_NAME (op)); "missing ')' after \"%s\" operand", NODE_NAME (op));
......
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