From 3d1d65bfe6dad089b9c2a8d69f36ba5301a9509c Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sun, 22 May 2022 20:46:58 +0200 Subject: fix zero/sign extension of integer character constants An integer character constant has type 'int' but, subtly enough, its value is the one of a 'char' converted to an 'int'. So, do this conversion. Also set the type of wide character constants from 'long' to 'wchar_t'. Link: https://lore.kernel.org/r/20210927130253.GH2083@kadam Reported-by: Dan Carpenter Reported-by: Rasmus Villemoes Signed-off-by: Luc Van Oostenryck --- expression.c | 10 +++++++++- validation/char-constant-signed.c | 9 +++++++++ validation/char-constant-unsigned.c | 9 +++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 validation/char-constant-signed.c create mode 100644 validation/char-constant-unsigned.c diff --git a/expression.c b/expression.c index 221d7780..efdaa367 100644 --- a/expression.c +++ b/expression.c @@ -427,8 +427,16 @@ struct token *primary_expression(struct token *token, struct expression **tree) case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3: expr = alloc_expression(token->pos, EXPR_VALUE); expr->flags = CEF_SET_CHAR; - expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype; get_char_constant(token, &expr->value); + + // TODO: handle 'u8', 'u' & 'U' prefixes. + if (token_type(token) < TOKEN_WIDE_CHAR) { + expr->ctype = &char_ctype; + cast_value(expr, &int_ctype, expr, expr->ctype); + expr->ctype = &int_ctype; + } else { + expr->ctype = wchar_ctype; + } token = token->next; break; diff --git a/validation/char-constant-signed.c b/validation/char-constant-signed.c new file mode 100644 index 00000000..be0fd5ce --- /dev/null +++ b/validation/char-constant-signed.c @@ -0,0 +1,9 @@ +int test(void) { return '\377' == -1; } + +/* + * check-name: char-constant-signed + * check-command: test-linearize -Wno-decl -fsigned-char $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/char-constant-unsigned.c b/validation/char-constant-unsigned.c new file mode 100644 index 00000000..d5642b16 --- /dev/null +++ b/validation/char-constant-unsigned.c @@ -0,0 +1,9 @@ +int test(void) { return '\377' == 255; } + +/* + * check-name: char-constant-unsigned + * check-command: test-linearize -Wno-decl -funsigned-char $file + * + * check-output-ignore + * check-output-returns: 1 + */ -- cgit 1.2.3-korg