[PATCH] delay 'empty character constant' warning to phase 5

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A subset of C syntax regarding character constants is:
	char-constant:
		' c-char-sequence '
	c-char-sequence:
		char
		c-char-sequence char

In short, when tokenized, a character constant must have at least
one character between the quotes. Consequently, sparse will
issue an error on empty character constants (unlike GCC).

However, sparse issues the error during tokenization (phase 3),
before preprocessing directives are handled (phase 4).
This means that code like:
	#if 0
	... ''
	#endif
will throw an error although the corresponding code is discarded.

Fix this by
1) silently accept empty char constants during tokenization
2) issue the diagnostic only when escape sequences are handled.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 char.c                                        |  5 +++++
 tokenize.c                                    |  7 +------
 validation/empty-char-constant.c              |  9 +++++++++
 validation/preprocessor/empty-char-constant.c | 13 +++++++++++++
 4 files changed, 28 insertions(+), 6 deletions(-)
 create mode 100644 validation/empty-char-constant.c
 create mode 100644 validation/preprocessor/empty-char-constant.c

diff --git a/char.c b/char.c
index f26b2a806696..730ae3f5d8ca 100644
--- a/char.c
+++ b/char.c
@@ -76,6 +76,11 @@ void get_char_constant(struct token *token, unsigned long long *val)
 	case TOKEN_WIDE_CHAR:
 		p = token->string->data;
 		end = p + token->string->length - 1;
+		if (end == p) {
+			sparse_error(token->pos, "empty character constant");
+			*val = 0;
+			return;
+		}
 		break;
 	case TOKEN_CHAR_EMBEDDED_0 ... TOKEN_CHAR_EMBEDDED_3:
 		end = p + type - TOKEN_CHAR;
diff --git a/tokenize.c b/tokenize.c
index c5ba6e6bbf5a..a7b6625bd2db 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -619,12 +619,7 @@ static int eat_string(int next, stream_t *stream, enum token_type type)
 		warning(stream_pos(stream), "string too long (%d bytes, %d bytes max)", len, MAX_STRING);
 		len = MAX_STRING;
 	}
-	if (delim == '\'' && len <= 4) {
-		if (len == 0) {
-			sparse_error(stream_pos(stream),
-				"empty character constant");
-			return nextchar(stream);
-		}
+	if (delim == '\'' && len && len <= 4) {
 		token_type(token) = type + len;
 		memset(buffer + len, '\0', 4 - len);
 		memcpy(token->embedded, buffer, 4);
diff --git a/validation/empty-char-constant.c b/validation/empty-char-constant.c
new file mode 100644
index 000000000000..f674037aae36
--- /dev/null
+++ b/validation/empty-char-constant.c
@@ -0,0 +1,9 @@
+static int a = '';
+
+/*
+ * check-name: empty-char-constant
+ *
+ * check-error-start
+empty-char-constant.c:1:16: error: empty character constant
+ * check-error-end
+ */
diff --git a/validation/preprocessor/empty-char-constant.c b/validation/preprocessor/empty-char-constant.c
new file mode 100644
index 000000000000..2c2481598884
--- /dev/null
+++ b/validation/preprocessor/empty-char-constant.c
@@ -0,0 +1,13 @@
+#if 0
+	''
+#endif
+
+/*
+ * check-name: empty-char-constant
+ * check-command: sparse -E $file
+ *
+ * check-output-start
+
+
+ * check-output-end
+ */
-- 
2.28.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux