summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-09-01 06:34:58 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-09-01 07:08:34 -0700
commit63b80f8cc181ded154668e60ac2cf0a6a82d118f (patch)
tree291b818f4ec95f5f8cb59387a1dd03735fdddfb1
parentc3c25a7ab8507c9c6b21137de03b5d94c2420369 (diff)
glsl2: Disallow function declarations within function definitions in GLSL 1.20
The GLSL 1.20 spec specifically disallows this, but it was allowed in GLSL 1.10. Fixes piglit test cases local-function-0[13].frag and bugzilla #29921.
-rw-r--r--src/glsl/ast_to_hir.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 148afd00e8..84aa6501c5 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2193,6 +2193,25 @@ ast_function::hir(exec_list *instructions,
const char *const name = identifier;
+ /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
+ *
+ * "Function declarations (prototypes) cannot occur inside of functions;
+ * they must be at global scope, or for the built-in functions, outside
+ * the global scope."
+ *
+ * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
+ *
+ * "User defined functions may only be defined within the global scope."
+ *
+ * Note that this language does not appear in GLSL 1.10.
+ */
+ if ((state->current_function != NULL) && (state->language_version != 110)) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "declaration of function `%s' not allowed within "
+ "function body", name);
+ }
+
/* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
*
* "Identifiers starting with "gl_" are reserved for use by
@@ -2275,7 +2294,23 @@ ast_function::hir(exec_list *instructions,
}
/* Emit the new function header */
- instructions->push_tail(f);
+ if (state->current_function == NULL)
+ instructions->push_tail(f);
+ else {
+ /* IR invariants disallow function declarations or definitions nested
+ * within other function definitions. Insert the new ir_function
+ * block in the instruction sequence before the ir_function block
+ * containing the current ir_function_signature.
+ *
+ * This can only happen in a GLSL 1.10 shader. In all other GLSL
+ * versions this nesting is disallowed. There is a check for this at
+ * the top of this function.
+ */
+ ir_function *const curr =
+ const_cast<ir_function *>(state->current_function->function());
+
+ curr->insert_before(f);
+ }
}
/* Verify the return type of main() */