diff options
Diffstat (limited to 'libcpp/macro.c')
-rw-r--r-- | libcpp/macro.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/libcpp/macro.c b/libcpp/macro.c index 748635f..12681c3 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1434,6 +1434,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) { cpp_token *token; const cpp_token *ctoken; + bool following_paste_op = false; + const char *paste_op_error_msg = + N_("'##' cannot appear at either end of a macro expansion"); /* Get the first token of the expansion (or the '(' of a function-like macro). */ @@ -1527,26 +1530,34 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) } if (token->type == CPP_EOF) - break; + { + /* Paste operator constraint 6.10.3.3.1: + Token-paste ##, can appear in both object-like and + function-like macros, but not at the end. */ + if (following_paste_op) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + return false; + } + break; + } /* Paste operator constraint 6.10.3.3.1. */ if (token->type == CPP_PASTE) { /* Token-paste ##, can appear in both object-like and - function-like macros, but not at the ends. */ - if (--macro->count > 0) - token = lex_expansion_token (pfile, macro); - - if (macro->count == 0 || token->type == CPP_EOF) + function-like macros, but not at the beginning. */ + if (macro->count == 1) { - cpp_error (pfile, CPP_DL_ERROR, - "'##' cannot appear at either end of a macro expansion"); + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); return false; } + --macro->count; token[-1].flags |= PASTE_LEFT; } + following_paste_op = (token->type == CPP_PASTE); token = lex_expansion_token (pfile, macro); } |