Define the behavior of catch vis a vis local variables defined in the block.

There exists code (eg Parser.Tabular) that uses exceptions for control flow, and expects variables defined in the catch block to be cleared when the catch returns. Having the variables be cleared at a later time or out of order may cause the code to fail.

Consider:

int bangers;

#if __VERSION__ < 9.0
#define _destruct destroy
#endif

class Bang
{
  inherit Pike.DestructImmediate;

  protected void create()
  {
    bangers++;
  }

  protected int _destruct()
  {
    bangers--;
    error("Bang!\n");
  }
}

mixed a(int i)
{
  mixed err = catch {
    Bang bang = Bang();

    if (i) error("Other!\n");
  };

  werror("#%d: Bangers: %d\n", i, bangers);
  if (err) {
    werror("Error: %O\n", err = describe_error(err));
  } else {
    werror("No error.\n");
  }
  return err;
}

int main()
{
  for (int i = 0; i < 2; i++) {
    mixed err = catch {
      mixed val = a(i);
      werror("#%d: bangers: %d, val: %O\n", i, bangers, val);
    };
    if (err) {
      werror("#%d: a(%d) failed: %O\n", i, i, describe_error(err));
    }
  }
}

This issue causes the Parser.Tabular testsuite to hang.

Edited by Henrik (Grubba) Grubbström