[llvm-commits] [llvm-gcc-4.2] r105902 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Bill Wendling isanbard at gmail.com
Sat Jun 12 17:43:21 PDT 2010


Author: void
Date: Sat Jun 12 19:43:21 2010
New Revision: 105902

URL: http://llvm.org/viewvc/llvm-project?rev=105902&view=rev
Log:
Limit the inclusion of an implicit "catch-all" to those selectors which are
clean-ups and which don't have a catch-all already. The reason for this is
because it breaks code that doesn't expect a catch-all. Take this example:

static void ThrowSomething() {
  throw "C++";
  printf("coucou\n");
}

static void CatchSomething() {
  @try {
    ThrowSomething();        
  } @catch(id e) {
    printf("ObjC exception\n");
  }
}

The CatchSomething function will generate an exception table that says that it
catches "id" and has a catch-all. However, the code calls
_Unwind_Resume_or_Rethrow in the catch-all instance. That causes libunwind to
assert, because it's not expecting that call.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=105902&r1=105901&r2=105902&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat Jun 12 19:43:21 2010
@@ -2098,6 +2098,7 @@
     foreach_reachable_handler(i, false, AddHandler, &Handlers);
 
     bool HasCleanup = false;
+    bool HasCatchAll = false;
     static GlobalVariable *CatchAll = 0;
 
     for (std::vector<struct eh_region *>::iterator I = Handlers.begin(),
@@ -2137,6 +2138,7 @@
           }
 
           Args.push_back(CatchAll);
+          HasCatchAll = true;
         } else {
           // Add the type infos.
           for (; TypeList; TypeList = TREE_CHAIN(TypeList)) {
@@ -2151,18 +2153,17 @@
     }
 
     if (can_throw_external_1(i, false)) {
-      if (HasCleanup && Args.size() == 2) {
-        Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0));
-      } else {
-        // Some exceptions from this region may not be caught by any handler.
-        // Since invokes are required to branch to the unwind label no matter
-        // what exception is being unwound, append a catch-all.
-
-        // The representation of a catch-all is language specific.
-        if (USING_SJLJ_EXCEPTIONS || !lang_eh_catch_all) {
-          // Use a "cleanup" - this should be good enough for most languages.
+      if (HasCleanup) {
+        if (Args.size() == 2 || USING_SJLJ_EXCEPTIONS || !lang_eh_catch_all) {
+          // Insert the sentinal indicating that this is a cleanup-only
+          // selector.  It may also be the representation of a catch-all for
+          // some languages.
           Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0));
-        } else {
+        } else if (!HasCatchAll) {
+          // Some exceptions from this region may not be caught by any handler.
+          // Since invokes are required to branch to the unwind label no matter
+          // what exception is being unwound, append a catch-all.
+
           if (!CatchAll) {
             Constant *Init = 0;
             tree catch_all_type = lang_eh_catch_all();





More information about the llvm-commits mailing list