[cfe-commits] r56751 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Daniel Dunbar daniel at zuster.org
Sat Sep 27 00:03:52 PDT 2008


Author: ddunbar
Date: Sat Sep 27 02:03:52 2008
New Revision: 56751

URL: http://llvm.org/viewvc/llvm-project?rev=56751&view=rev
Log:
Bug fix, make sure to initialize exception object (to rethrow) even
when there are no @catch blocks.

Also, eliminated unneeded alloca for the rethrow object.

Also, avoid generating code to rethrow exception if the exception will
trivially always be caught.

Modified:
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=56751&r1=56750&r2=56751&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sat Sep 27 02:03:52 2008
@@ -1422,19 +1422,17 @@
   
   // Emit the "exception in @try" block.
   CGF.EmitBlock(ExceptionInTryBlock);
-  
-  if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) {
-    // Allocate memory for the caught exception and extract it from the 
-    // exception data.
-    llvm::Value *CaughtPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy);
-    llvm::Value *Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
-                                                  ExceptionData);
-    CGF.Builder.CreateStore(Extract, CaughtPtr);
-    
-    // Enter a new exception try block 
-    // (in case a @catch block throws an exception).
+
+  // Retrieve the exception object.  We may emit multiple blocks but
+  // nothing can cross this so the value is already in SSA form.
+  llvm::Value *Caught = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
+                                               ExceptionData,
+                                               "caught");
+  if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) {    
+    // Enter a new exception try block (in case a @catch block throws
+    // an exception).
     CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
-    
+        
     llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
                                                        JmpBufPtr, "result");
     
@@ -1450,29 +1448,31 @@
     
     CGF.EmitBlock(CatchBlock);
         
-    // Handle catch list
+    // Handle catch list. As a special case we check if everything is
+    // matched and avoid generating code for falling off the end if
+    // so.
+    bool AllMatched = false;
     for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
       llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch");
-      llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught");
 
       QualType T;
-      bool MatchesAll = false;
       const DeclStmt *CatchParam = 
         cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt());
-
+      const ValueDecl *VD = 0;
+      
       // catch(...) always matches.
-      if (!CatchParam)
-        MatchesAll = true;
-      else {
-        QualType PT = cast<ValueDecl>(CatchParam->getDecl())->getType();
-        T = PT->getAsPointerType()->getPointeeType();
+      if (!CatchParam) {
+        AllMatched = true;
+      } else {
+        VD = cast<ValueDecl>(CatchParam->getDecl());
         
         // catch(id e) always matches.
-        if (CGF.getContext().isObjCIdType(T))
-          MatchesAll = true;
+        const PointerType *PT = VD->getType()->getAsPointerType();
+        if (PT && CGF.getContext().isObjCIdType(PT->getPointeeType()))
+          AllMatched = true;
       }
       
-      if (MatchesAll) {   
+      if (AllMatched) {   
         if (CatchParam) {
           CGF.EmitStmt(CatchParam);
           
@@ -1485,7 +1485,6 @@
         
         CGF.EmitStmt(CatchStmt->getCatchBody());
         CGF.Builder.CreateBr(FinallyBlock);
-        CGF.EmitBlock(NextCatchBlock);        
         break;
       }
       
@@ -1523,20 +1522,21 @@
       CGF.EmitBlock(NextCatchBlock);
     }
 
-    // None of the handlers caught the exception, so store it and rethrow
-    // it later.
-    llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught");
-    CGF.Builder.CreateStore(Caught, RethrowPtr);
-    CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn,
-                           ExceptionData);
-    
-    CGF.Builder.CreateBr(FinallyBlock);
-    
-    CGF.EmitBlock(ExceptionInCatchBlock);
+    if (!AllMatched) {
+      // None of the handlers caught the exception, so store it to be
+      // rethrown at the end of the @finally block.
+      CGF.Builder.CreateStore(Caught, RethrowPtr);
+      CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
+      CGF.Builder.CreateBr(FinallyBlock);
+    }
     
-    Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
-                                     ExceptionData);
-    CGF.Builder.CreateStore(Extract, RethrowPtr);
+    // Emit the exception handler for the @catch blocks.
+    CGF.EmitBlock(ExceptionInCatchBlock);    
+    CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
+                                                   ExceptionData), 
+                            RethrowPtr);
+  } else {
+    CGF.Builder.CreateStore(Caught, RethrowPtr);
   }
   
   // Emit the @finally block.





More information about the cfe-commits mailing list