summaryrefslogtreecommitdiffstats
path: root/src/glsl/linker.cpp
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-11-22 12:37:22 -0800
committerPaul Berry <[email protected]>2013-11-26 13:22:24 -0800
commitd7fa9eb003bf0d2016ca1f7cb14e59ad22e89b93 (patch)
tree10d75afb7a1827afa845fae4e70c9bd988f1e50b /src/glsl/linker.cpp
parent9dfcb05fa649ee7a573eab3d16851ebd4cb96010 (diff)
glsl/linker: Validate IR just before reparenting.
If reparent_ir() is called on invalid IR, then there's a danger that it will fail to reparent all of the necessary nodes. For example, if the IR contains an ir_dereference_variable which refers to an ir_variable that's not in the tree, that ir_variable won't get reparented, resulting in subtle use-after-free bugs once the non-reparented nodes are freed. (This is exactly what happened in the bug fixed by the previous commit). This patch makes this kind of bug far easier to track down, by transforming it from a use-after-free bug into an explicit IR validation error. Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r--src/glsl/linker.cpp5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index fac186a6379..1366077f784 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2396,6 +2396,11 @@ done:
if (prog->_LinkedShaders[i] == NULL)
continue;
+ /* Do a final validation step to make sure that the IR wasn't
+ * invalidated by any modifications performed after intrastage linking.
+ */
+ validate_ir_tree(prog->_LinkedShaders[i]->ir);
+
/* Retain any live IR, but trash the rest. */
reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);