[PATCH] D14669: [EH] Keep filter types even if the type has been caught.

Andy Kaylor via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 17:23:50 PST 2015


andrew.w.kaylor created this revision.
andrew.w.kaylor added reviewers: rnk, majnemer, rjmccall.
andrew.w.kaylor added a subscriber: llvm-commits.
andrew.w.kaylor set the repository for this revision to rL LLVM.

I came across a problem in testing on Linux where the handling of unexpected exception types wasn't working correctly if the unexpected handler tried to throw a type that the call site would have caught.  The following code demonstrates the issue:
```
#include <exception>
#include <iostream>
#include <cstdlib>

void unexpected() {
  std::cout << "Throwing in unexpected(): 1\n";
  throw 1;
}

void foo() throw (int) {
  std::set_unexpected(unexpected);
  try {
    std::cout << "Throwing in foo(): 2.0\n";
    throw 2.0;
  } catch (int i) {
    std::cout << "Caught in foo(): " << i << "\n";
    exit(EXIT_FAILURE);
  }
}

int main() {
  try {
    foo();
  } catch (int i) {
    std::cout << "Caught in main(): " << i << "\n";
  } catch (...) {
    std::cout << "Caught in main(): catch all\n";
    exit(EXIT_FAILURE);
  }
  return 0;
}
```
The "2.0" exception thrown in foo should go to the unexpected handler and the '1' exception thrown by the unexpected handler should be caught by the 'int' handler in main.  Instead, without my proposed changes the runtime library calls terminate() when '1' is thrown from the unexpected handler.  Near as I can tell, the runtime is looking at the exception record for the call site in the LSDA when the unexpected handler throws an exception to see if the throw exception meets the call site's filter requirements.

The STL documentation for std::set_unexpected() says this: "The unexpected handler function can handle the exception and shall end either by terminating (calling terminate or some other method, such as exit or abort) or by throwing an exception (even rethrowing the same exception again). If the exception thrown (or rethrown) is not in the function's dynamic-exception-specification but bad_exception is, a bad_exception is thrown. Otherwise, if the new exception is not in the dynamic-exception-specification either, terminate is automatically called."

I'm not certain that this is an issue for Objective C and I'm not sure how to test that.  I'm just guessing that it might be similar, but I will happily exclude it if it doesn't apply.  I also don't know if this problem applies to any other personality functions, but given how long the code has been in its current state I would guess not.

Repository:
  rL LLVM

http://reviews.llvm.org/D14669

Files:
  lib/Transforms/InstCombine/InstructionCombining.cpp
  test/Transforms/InstCombine/LandingPadClauses.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14669.40190.patch
Type: text/x-patch
Size: 4397 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151114/edf9f58e/attachment.bin>


More information about the llvm-commits mailing list