summaryrefslogtreecommitdiffstats
path: root/xlators/experimental
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/experimental')
-rwxr-xr-xxlators/experimental/fdl/src/gen_recon.py24
1 files changed, 23 insertions, 1 deletions
diff --git a/xlators/experimental/fdl/src/gen_recon.py b/xlators/experimental/fdl/src/gen_recon.py
index 26318f92d88..67f9ea9ebd3 100755
--- a/xlators/experimental/fdl/src/gen_recon.py
+++ b/xlators/experimental/fdl/src/gen_recon.py
@@ -101,7 +101,29 @@ def get_special_subs (name, args, fop_type):
.replace("@ARGTYPE@",arg[2])
cleanup_key = recon_type + "_CLEANUP"
if fragments.has_key(cleanup_key):
- cleanups += fragments[cleanup_key].replace("@ARGNAME@",arg[1])
+ new_frag = fragments[cleanup_key].replace("@ARGNAME@",arg[1])
+ # Make sure these get added in *reverse* order. Otherwise, a
+ # failure for an earlier argument might goto a label that falls
+ # through to the cleanup code for a variable associated with a
+ # later argument, but that variable might not even have been
+ # *declared* (let alone initialized) yet. Consider the following
+ # case.
+ #
+ # process argument A (on failure goto cleanup_A)
+ # set error label to cleanup_A
+ #
+ # declare pointer variable for argument B
+ # process argument B (on failure goto cleanup_B)
+ #
+ # cleanup_A:
+ # /* whatever */
+ # cleanup_B:
+ # free pointer variable <= "USED BUT NOT SET" error here
+ #
+ # By adding these in reverse order, we ensure that cleanup_B is
+ # actually *before* cleanup_A, and nothing will try to do the free
+ # until we've actually attempted processing of B.
+ cleanups = new_frag + cleanups
if 'nosync' in arg[4:]:
code += "\t(void)%s;\n" % arg[1];
continue