[Mesa-dev,01/23] glsl/glcpp: Emit proper error for #define with a non-identifier

Submitted by Carl Worth on June 26, 2014, 10:19 p.m.

Details

Message ID 1403821163-22341-2-git-send-email-cworth@cworth.org
State New
Headers show

Not browsing as part of any series.

Commit Message

Carl Worth June 26, 2014, 10:19 p.m.
Previously, if the preprocessor encountered a #define with a non-identifier,
such as:

	#define 123 456

The lexer had no explicit rules to match non-identifiers in the <DEFINE> start
state. Because of this, flex's default rule was being invoked, (printing
characters to stdout), and all text was being discarded by the compiler until
the next identifier. As one can imagine, this led to all sorts of interesting
and surprising results.

Fix this by adding an explicit rule complementing the existing
identifier-based rules that should catch all non-identifiers after #define and
reliably give a well-formatted error message.

A new test is added to "make check" to ensure this bug stays fixed.

This commit also fixes the following Khronos GLES3 CTS test:

	define_non_identifier_vertex

(The "fragment" variant was passing earlier only because the preprocessor was
behaving so randomly and causing the compilation to fail. It's lucky, in fact,
that the "vertex" version succesfully compiled so we could find and fix this
bug.)
---
 src/glsl/glcpp/glcpp-lex.l                                | 6 ++++++
 src/glsl/glcpp/tests/128-define-non-identifier.c          | 1 +
 src/glsl/glcpp/tests/128-define-non-identifier.c.expected | 2 ++
 3 files changed, 9 insertions(+)
 create mode 100644 src/glsl/glcpp/tests/128-define-non-identifier.c
 create mode 100644 src/glsl/glcpp/tests/128-define-non-identifier.c.expected

Patch hide | download patch | download mbox

diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l
index a1a8e76..1a2e7e2 100644
--- a/src/glsl/glcpp/glcpp-lex.l
+++ b/src/glsl/glcpp/glcpp-lex.l
@@ -259,6 +259,12 @@  HEXADECIMAL_INTEGER	0[xX][0-9a-fA-F]+[uU]?
 	return OBJ_IDENTIFIER;
 }
 
+<DEFINE>[^_a-zA-Z]{NONSPACE}* {
+	BEGIN INITIAL;
+	glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext);
+	return INTEGER_STRING;
+}
+
 {HASH}undef {
 	yyextra->space_tokens = 0;
 	return HASH_UNDEF;
diff --git a/src/glsl/glcpp/tests/128-define-non-identifier.c b/src/glsl/glcpp/tests/128-define-non-identifier.c
new file mode 100644
index 0000000..a229179
--- /dev/null
+++ b/src/glsl/glcpp/tests/128-define-non-identifier.c
@@ -0,0 +1 @@ 
+#define 123 456
diff --git a/src/glsl/glcpp/tests/128-define-non-identifier.c.expected b/src/glsl/glcpp/tests/128-define-non-identifier.c.expected
new file mode 100644
index 0000000..b460357
--- /dev/null
+++ b/src/glsl/glcpp/tests/128-define-non-identifier.c.expected
@@ -0,0 +1,2 @@ 
+0:1(10): preprocessor error: #define followed by a non-identifier: 123
+0:1(10): preprocessor error: syntax error, unexpected INTEGER_STRING, expecting FUNC_IDENTIFIER or OBJ_IDENTIFIER