diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-01-07 14:16:12 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-12 10:13:10 -0500 |
commit | 3dbed8ac24a2b4b24bc9776d89ea5328f1424a63 (patch) | |
tree | 3086bdde5dc203c7ac354a20ea52623c3380d2f8 | |
parent | 959bd8973bfcfced69715a522007662929ae6d48 (diff) | |
download | sparse-master.tar.gz |
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | pre-process.c | 27 | ||||
-rw-r--r-- | validation/preprocessor/wide.c | 15 |
2 files changed, 41 insertions, 1 deletions
diff --git a/pre-process.c b/pre-process.c index 9e5df5c3..e5f56b40 100644 --- a/pre-process.c +++ b/pre-process.c @@ -407,6 +407,8 @@ static void expand_arguments(int count, struct arg *args) * Possibly valid combinations: * - ident + ident -> ident * - ident + number -> ident unless number contains '.', '+' or '-'. + * - 'L' + char constant -> wide char constant + * - 'L' + string literal -> wide string literal * - number + number -> number * - number + ident -> number * - number + '.' -> number @@ -422,6 +424,13 @@ static enum token_type combine(struct token *left, struct token *right, char *p) if (t1 != TOKEN_IDENT && t1 != TOKEN_NUMBER && t1 != TOKEN_SPECIAL) return TOKEN_ERROR; + if (t1 == TOKEN_IDENT && left->ident == &L_ident) { + if (t2 >= TOKEN_CHAR && t2 < TOKEN_WIDE_CHAR) + return t2 + TOKEN_WIDE_CHAR - TOKEN_CHAR; + if (t2 == TOKEN_STRING) + return TOKEN_WIDE_STRING; + } + if (t2 != TOKEN_IDENT && t2 != TOKEN_NUMBER && t2 != TOKEN_SPECIAL) return TOKEN_ERROR; @@ -464,9 +473,10 @@ static enum token_type combine(struct token *left, struct token *right, char *p) static int merge(struct token *left, struct token *right) { static char buffer[512]; + enum token_type res = combine(left, right, buffer); int n; - switch (combine(left, right, buffer)) { + switch (res) { case TOKEN_IDENT: left->ident = built_in_ident(buffer); left->pos.noexpand = 0; @@ -489,6 +499,21 @@ static int merge(struct token *left, struct token *right) return 1; } } + break; + + case TOKEN_WIDE_CHAR: + case TOKEN_WIDE_STRING: + token_type(left) = res; + left->pos.noexpand = 0; + left->string = right->string; + return 1; + + case TOKEN_WIDE_CHAR + 1 ... TOKEN_WIDE_CHAR + 4: + token_type(left) = res; + left->pos.noexpand = 0; + memcpy(left->embedded, right->embedded, 4); + return 1; + default: ; } diff --git a/validation/preprocessor/wide.c b/validation/preprocessor/wide.c new file mode 100644 index 00000000..21b643ce --- /dev/null +++ b/validation/preprocessor/wide.c @@ -0,0 +1,15 @@ +#define A(x) L##x +A('a') +A("bc") +/* + * check-name: wide char token-pasting + * check-description: Used to cause infinite recursion. + * check-command: sparse -E $file + * + * check-output-start + +L'a' +L"bc" + * check-output-end + */ + |