Commit 729a01f7 by Nathan Sidwell Committed by Nathan Sidwell

[PATCH] Macro definition parameter parsing

https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00977.html
	libcpp/
	* internal.h (_cpp_save_parameter): Take parmno, not macro.
	(_cpp_unsave_parameters): Declare.
	* macro.c (_cpp_save_parameter): Take parm number, not macro.
	Return true on success.
	(_cpp_unsave_parameters): New.
	(parse_params): Take parm_no and variadic pointers, not macro.
	Reimplement parsing logic.
	(create_iso_definition): Adjust parse_params changes.  Call
	_cpp_unsave_parameters here.
	(_cpp_create_definition): Don't unsave params here.
	* traditional.c (scan_parameters): Take n_param pointer, adjust.
	(_cpp_create_trad_definition): Ajust scan_parameters change.  Call
	_cpp_unsave_parameters.
	gcc/testsuite/
	* gcc.dg/cpp/macsyntx.c: Adjust expected errors.
	* gcc.dg/cpp/macsyntx2.c: likewise.

From-SVN: r263600
parent c37da7c0
2018-08-16 Nathan Sidwell <nathan@acm.org>
* gcc.dg/cpp/macsyntx.c: Adjust expected errors.
* gcc.dg/cpp/macsyntx2.c: likewise.
2018-08-15 Uros Bizjak <ubizjak@gmail.com> 2018-08-15 Uros Bizjak <ubizjak@gmail.com>
PR testsuite/86745 PR testsuite/86745
......
...@@ -21,14 +21,14 @@ ...@@ -21,14 +21,14 @@
#define ; /* { dg-error "identifier" } */ #define ; /* { dg-error "identifier" } */
#define SEMI; /* { dg-warning "space" } */ #define SEMI; /* { dg-warning "space" } */
#define foo(X /* { dg-error "missing" } */ #define foo(X /* { dg-error "expected" } */
#define foo\ #define foo\
(X,) /* { dg-error "parameter name" } */ (X,) /* { dg-error "parameter name" } */
#define foo(, X) /* { dg-error "parameter name" } */ #define foo(, X) /* { dg-error "parameter name" } */
#define foo(X, X) /* { dg-error "duplicate" } */ #define foo(X, X) /* { dg-error "duplicate" } */
#define foo(X Y) /* { dg-error "comma" } */ #define foo(X Y) /* { dg-error "expected" } */
#define foo(() /* { dg-error "may not appear" } */ #define foo(() /* { dg-error "parameter name" } */
#define foo(..., X) /* { dg-error "missing" } */ #define foo(..., X) /* { dg-error "expected" } */
#define foo \ #define foo \
__VA_ARGS__ /* { dg-warning "__VA_ARGS__" } */ __VA_ARGS__ /* { dg-warning "__VA_ARGS__" } */
#define goo(__VA_ARGS__) /* { dg-warning "__VA_ARGS__" } */ #define goo(__VA_ARGS__) /* { dg-warning "__VA_ARGS__" } */
......
...@@ -21,14 +21,14 @@ ...@@ -21,14 +21,14 @@
#define ; /* { dg-error "identifier" } */ #define ; /* { dg-error "identifier" } */
#define SEMI; /* { dg-warning "space" } */ #define SEMI; /* { dg-warning "space" } */
#define foo(X /* { dg-error "missing" } */ #define foo(X /* { dg-error "expected" } */
#define foo\ #define foo\
(X,) /* { dg-error "parameter name" } */ (X,) /* { dg-error "parameter name" } */
#define foo(, X) /* { dg-error "parameter name" } */ #define foo(, X) /* { dg-error "parameter name" } */
#define foo(X, X) /* { dg-error "duplicate" } */ #define foo(X, X) /* { dg-error "duplicate" } */
#define foo(X Y) /* { dg-error "comma" } */ #define foo(X Y) /* { dg-error "expected" } */
#define foo(() /* { dg-error "may not appear" } */ #define foo(() /* { dg-error "parameter name" } */
#define foo(..., X) /* { dg-error "missing" } */ #define foo(..., X) /* { dg-error "expected" } */
#define foo \ #define foo \
__VA_ARGS__ /* { dg-warning "__VA_ARGS__" } */ __VA_ARGS__ /* { dg-warning "__VA_ARGS__" } */
#define goo(__VA_ARGS__) /* { dg-warning "__VA_ARGS__" } */ #define goo(__VA_ARGS__) /* { dg-warning "__VA_ARGS__" } */
......
2018-08-16 Nathan Sidwell <nathan@acm.org> 2018-08-16 Nathan Sidwell <nathan@acm.org>
libcpp/ * internal.h (_cpp_save_parameter): Take parmno, not macro.
(_cpp_unsave_parameters): Declare.
* macro.c (_cpp_save_parameter): Take parm number, not macro.
Return true on success.
(_cpp_unsave_parameters): New.
(parse_params): Take parm_no and variadic pointers, not macro.
Reimplement parsing logic.
(create_iso_definition): Adjust parse_params changes. Call
_cpp_unsave_parameters here.
(_cpp_create_definition): Don't unsave params here.
* traditional.c (scan_parameters): Take n_param pointer, adjust.
(_cpp_create_trad_definition): Ajust scan_parameters change. Call
_cpp_unsave_parameters.
* include/cpplib.h (cpp_user_macro_p, cpp_builtin_macro_p) * include/cpplib.h (cpp_user_macro_p, cpp_builtin_macro_p)
(cpp_macro_p): New inlines. (cpp_macro_p): New inlines.
* directives.c (do_pragma_poison): Use cpp_macro_p. * directives.c (do_pragma_poison): Use cpp_macro_p.
......
...@@ -632,8 +632,9 @@ extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); ...@@ -632,8 +632,9 @@ extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *);
extern void _cpp_pop_context (cpp_reader *); extern void _cpp_pop_context (cpp_reader *);
extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *, extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *,
const unsigned char *, size_t); const unsigned char *, size_t);
extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *, extern bool _cpp_save_parameter (cpp_reader *, unsigned, cpp_hashnode *,
cpp_hashnode *); cpp_hashnode *);
extern void _cpp_unsave_parameters (cpp_reader *, unsigned);
extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *, extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *,
unsigned int); unsigned int);
extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *,
......
...@@ -89,7 +89,7 @@ static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *); ...@@ -89,7 +89,7 @@ static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *);
static const uchar *copy_comment (cpp_reader *, const uchar *, int); static const uchar *copy_comment (cpp_reader *, const uchar *, int);
static void check_output_buffer (cpp_reader *, size_t); static void check_output_buffer (cpp_reader *, size_t);
static void push_replacement_text (cpp_reader *, cpp_hashnode *); static void push_replacement_text (cpp_reader *, cpp_hashnode *);
static bool scan_parameters (cpp_reader *, cpp_macro *); static bool scan_parameters (cpp_reader *, unsigned *);
static bool recursive_macro (cpp_reader *, cpp_hashnode *); static bool recursive_macro (cpp_reader *, cpp_hashnode *);
static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int); static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int);
static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *, static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *,
...@@ -1082,11 +1082,12 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro) ...@@ -1082,11 +1082,12 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
duplicate parameter). On success, CUR (pfile->context) is just duplicate parameter). On success, CUR (pfile->context) is just
past the closing parenthesis. */ past the closing parenthesis. */
static bool static bool
scan_parameters (cpp_reader *pfile, cpp_macro *macro) scan_parameters (cpp_reader *pfile, unsigned *n_ptr)
{ {
const uchar *cur = CUR (pfile->context) + 1; const uchar *cur = CUR (pfile->context) + 1;
bool ok; bool ok;
unsigned nparms = 0;
for (;;) for (;;)
{ {
cur = skip_whitespace (pfile, cur, true /* skip_comments */); cur = skip_whitespace (pfile, cur, true /* skip_comments */);
...@@ -1095,8 +1096,9 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro) ...@@ -1095,8 +1096,9 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro)
{ {
struct cpp_hashnode *id = lex_identifier (pfile, cur); struct cpp_hashnode *id = lex_identifier (pfile, cur);
ok = false; ok = false;
if (_cpp_save_parameter (pfile, macro, id, id)) if (!_cpp_save_parameter (pfile, nparms, id, id))
break; break;
nparms++;
cur = skip_whitespace (pfile, CUR (pfile->context), cur = skip_whitespace (pfile, CUR (pfile->context),
true /* skip_comments */); true /* skip_comments */);
if (*cur == ',') if (*cur == ',')
...@@ -1108,10 +1110,12 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro) ...@@ -1108,10 +1110,12 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro)
break; break;
} }
ok = (*cur == ')' && macro->paramc == 0); ok = (*cur == ')' && !nparms);
break; break;
} }
*n_ptr = nparms;
if (!ok) if (!ok)
cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list"); cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list");
...@@ -1181,6 +1185,7 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) ...@@ -1181,6 +1185,7 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
const uchar *cur; const uchar *cur;
uchar *limit; uchar *limit;
cpp_context *context = pfile->context; cpp_context *context = pfile->context;
unsigned nparms = 0;
/* The context has not been set up for command line defines, and CUR /* The context has not been set up for command line defines, and CUR
has not been updated for the macro name for in-file defines. */ has not been updated for the macro name for in-file defines. */
...@@ -1192,7 +1197,8 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) ...@@ -1192,7 +1197,8 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
/* Is this a function-like macro? */ /* Is this a function-like macro? */
if (* CUR (context) == '(') if (* CUR (context) == '(')
{ {
bool ok = scan_parameters (pfile, macro); bool ok = scan_parameters (pfile, &nparms);
macro->paramc = nparms;
/* Remember the params so we can clear NODE_MACRO_ARG flags. */ /* Remember the params so we can clear NODE_MACRO_ARG flags. */
macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
...@@ -1217,6 +1223,8 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) ...@@ -1217,6 +1223,8 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
_cpp_scan_out_logical_line (pfile, macro, false); _cpp_scan_out_logical_line (pfile, macro, false);
pfile->state.prevent_expansion--; pfile->state.prevent_expansion--;
_cpp_unsave_parameters (pfile, nparms);
if (!macro) if (!macro)
return false; return false;
......
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