Next: , Previous: Jumps, Up: Statements


11.7.6 清除

对于C++局部对象的析构,以及类似的动态清除操作在GIMPLE中通过一个TRY_FINALLY_EXPR来表示。TRY_FINALLY_EXPR有两个操作数,均为要执行的语句序列。第一个序列会被执行。当其执行完毕时,第二个序列会被执行。

第一个序列可以按照下列方式来执行完毕:

  1. 执行了序列中的最后一条语句,并结束。
  2. 执行一个goto语句(GOTO_EXPR),跳到序列之外的一个普通标号。 t
  3. 执行一个return语句(RETURN_EXPR)。
  4. 抛出一个异常。这在当前没有用GIMPLE显式的表示。

如果第一个序列通过调用setjmpexit,或者其它不返回的函数,来执行完毕,则第二个序列不会被执行。如果第一个序列通过一个非局部goto或者一个计算goto(总的来说,编译器不知道这样一个goto语句是否会退出第一个序列,所以我们假设其没有退出)来执行完毕,则第二个序列也不会被执行。

第二个序列被执行完之后,如果其正常的执行到结尾,并结束,则只要第一个序列被继续执行,其也会被继续。

TRY_FINALLY_EXPR使流图变得复杂,因为清除工作需要在流出控制块的每条边上都出现;这就减少了将代码跨越这些边进行移动的自由。因此,运行于大多数优化过程之前的EH下降过程,通过显式的增加对每个边的清除操作,来消除这些表达式。再次抛出异常使用RESX_EXPR来表示。