summaryrefslogtreecommitdiff
path: root/src/glsl
diff options
context:
space:
mode:
authorErik Faye-Lund <kusmabite@gmail.com>2013-12-17 16:37:33 +0100
committerCarl Worth <cworth@cworth.org>2014-01-02 15:57:41 -0800
commitb8be00e5f203cdf8a69d7283e6fdc872e80cf5c9 (patch)
treeee6e354e9e4c7f112ef92d928f023a3e2f2b5762 /src/glsl
parent347f1493320e1bc2194c70d4d66bfe2b5883bf1e (diff)
glcpp: error on multiple #else/#elif directives
The preprocessor currently accepts multiple else/elif-groups per if-section. The GLSL-preprocessor is defined by the C++ specification, which defines the following parse-rule: if-section: if-group elif-groups(opt) else-group(opt) endif-line This clearly only allows a single else-group, that has to come after any elif-groups. So let's modify the code to follow the specification. Add test to prevent regressions. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Carl Worth <cworth@cworth.org> Cc: 10.0 <mesa-stable@lists.freedesktop.org> (cherry picked from commit eb212c5a302f0122a13b36dfdf07e91f951ae2e7)
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/glcpp/glcpp-parse.y23
-rw-r--r--src/glsl/glcpp/glcpp.h1
-rw-r--r--src/glsl/glcpp/tests/118-multiple-else.c6
-rw-r--r--src/glsl/glcpp/tests/118-multiple-else.c.expected8
-rw-r--r--src/glsl/glcpp/tests/119-elif-after-else.c6
-rw-r--r--src/glsl/glcpp/tests/119-elif-after-else.c.expected8
6 files changed, 51 insertions, 1 deletions
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index 7edc27488a0..451b72841cf 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -310,6 +310,11 @@ control_line:
_glcpp_parser_expand_and_lex_from (parser,
ELIF_EXPANDED, $2);
}
+ else if (parser->skip_stack &&
+ parser->skip_stack->has_else)
+ {
+ glcpp_error(& @1, parser, "#elif after #else");
+ }
else
{
_glcpp_parser_skip_stack_change_if (parser, & @1,
@@ -324,6 +329,11 @@ control_line:
{
glcpp_error(& @1, parser, "#elif with no expression");
}
+ else if (parser->skip_stack &&
+ parser->skip_stack->has_else)
+ {
+ glcpp_error(& @1, parser, "#elif after #else");
+ }
else
{
_glcpp_parser_skip_stack_change_if (parser, & @1,
@@ -332,7 +342,17 @@ control_line:
}
}
| HASH_ELSE {
- _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
+ if (parser->skip_stack &&
+ parser->skip_stack->has_else)
+ {
+ glcpp_error(& @1, parser, "multiple #else");
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
+ if (parser->skip_stack)
+ parser->skip_stack->has_else = true;
+ }
} NEWLINE
| HASH_ENDIF {
_glcpp_parser_skip_stack_pop (parser, & @1);
@@ -2024,6 +2044,7 @@ _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
node->type = SKIP_TO_ENDIF;
}
+ node->has_else = false;
node->next = parser->skip_stack;
parser->skip_stack = node;
}
diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h
index 8aaa551d128..ccae96c1df7 100644
--- a/src/glsl/glcpp/glcpp.h
+++ b/src/glsl/glcpp/glcpp.h
@@ -153,6 +153,7 @@ typedef enum skip_type {
typedef struct skip_node {
skip_type_t type;
+ bool has_else;
YYLTYPE loc; /* location of the initial #if/#elif/... */
struct skip_node *next;
} skip_node_t;
diff --git a/src/glsl/glcpp/tests/118-multiple-else.c b/src/glsl/glcpp/tests/118-multiple-else.c
new file mode 100644
index 00000000000..62ad49cf7bb
--- /dev/null
+++ b/src/glsl/glcpp/tests/118-multiple-else.c
@@ -0,0 +1,6 @@
+#if 0
+#else
+int foo;
+#else
+int bar;
+#endif
diff --git a/src/glsl/glcpp/tests/118-multiple-else.c.expected b/src/glsl/glcpp/tests/118-multiple-else.c.expected
new file mode 100644
index 00000000000..eaec4815076
--- /dev/null
+++ b/src/glsl/glcpp/tests/118-multiple-else.c.expected
@@ -0,0 +1,8 @@
+0:4(1): preprocessor error: multiple #else
+
+
+int foo;
+
+int bar;
+
+
diff --git a/src/glsl/glcpp/tests/119-elif-after-else.c b/src/glsl/glcpp/tests/119-elif-after-else.c
new file mode 100644
index 00000000000..9b9e9233bcb
--- /dev/null
+++ b/src/glsl/glcpp/tests/119-elif-after-else.c
@@ -0,0 +1,6 @@
+#if 0
+#else
+int foo;
+#elif 0
+int bar;
+#endif
diff --git a/src/glsl/glcpp/tests/119-elif-after-else.c.expected b/src/glsl/glcpp/tests/119-elif-after-else.c.expected
new file mode 100644
index 00000000000..33f05136158
--- /dev/null
+++ b/src/glsl/glcpp/tests/119-elif-after-else.c.expected
@@ -0,0 +1,8 @@
+0:4(1): preprocessor error: #elif after #else
+
+
+int foo;
+
+int bar;
+
+