diff options
author | Ian Romanick <[email protected]> | 2010-09-01 06:34:58 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-09-01 07:08:34 -0700 |
commit | 63b80f8cc181ded154668e60ac2cf0a6a82d118f (patch) | |
tree | 291b818f4ec95f5f8cb59387a1dd03735fdddfb1 /src | |
parent | c3c25a7ab8507c9c6b21137de03b5d94c2420369 (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.
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 148afd00e88..84aa6501c55 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() */ |