This looks like a recipe for disaster when you'll free something in the return path that shouldn't be freed because it's part of the function's result, or forget to free something in a success path. Just write
result=x;
goto cleanup;
if you meant result=x;
goto cleanup;
At least then you'll be able to follow the control flow without remembering what the magic macro does.
In your cleanup method you have to take the same care of parameters that you are putting results into as any other way you can deal with this. All it does is save you from repeating such logic at all the exit points.