[cfe-commits] r65964 - in /cfe/trunk: Driver/PrintParserCallbacks.cpp Driver/RewriteObjC.cpp include/clang/AST/Stmt.h include/clang/Parse/Action.h lib/AST/Stmt.cpp lib/AST/StmtPrinter.cpp lib/CodeGen/CGObjCMac.cpp lib/Parse/ParseObjc.cpp lib/Sema/Sema.h lib/Sema/SemaStmt.cpp

Steve Naroff snaroff at apple.com
Tue Mar 3 11:52:18 PST 2009


Author: snaroff
Date: Tue Mar  3 13:52:17 2009
New Revision: 65964

URL: http://llvm.org/viewvc/llvm-project?rev=65964&view=rev
Log:
Fix <rdar://problem/6640991> Exception handling executes wrong clause (Daniel, please verify).

Also necessary to fix:

<rdar://problem/6632061> [sema] non object types should not be allowed in @catch statements
<rdar://problem/6252237> [sema] qualified id should be disallowed in @catch statements


Modified:
    cfe/trunk/Driver/PrintParserCallbacks.cpp
    cfe/trunk/Driver/RewriteObjC.cpp
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaStmt.cpp

Modified: cfe/trunk/Driver/PrintParserCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/PrintParserCallbacks.cpp?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/Driver/PrintParserCallbacks.cpp (original)
+++ cfe/trunk/Driver/PrintParserCallbacks.cpp Tue Mar  3 13:52:17 2009
@@ -382,7 +382,7 @@
     // Objective-c statements
     virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
                                                   SourceLocation RParen,
-                                                  StmtArg Parm, StmtArg Body,
+                                                  DeclTy *Parm, StmtArg Body,
                                                   StmtArg CatchList) {
       llvm::cout << __FUNCTION__ << "\n";
       return StmtEmpty();

Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Tue Mar  3 13:52:17 2009
@@ -1567,7 +1567,7 @@
   bool sawIdTypedCatch = false;
   Stmt *lastCatchBody = 0;
   while (catchList) {
-    Stmt *catchStmt = catchList->getCatchParamStmt();
+    ParmVarDecl *catchDecl = catchList->getCatchParamDecl();
 
     if (catchList == S->getCatchStmts()) 
       buf = "if ("; // we are generating code for the first catch clause
@@ -1592,8 +1592,8 @@
       buf += "1) { id _tmp = _caught;";
       Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, 
                           buf.c_str(), buf.size());      
-    } else if (DeclStmt *declStmt = dyn_cast<DeclStmt>(catchStmt)) {
-      QualType t = dyn_cast<ValueDecl>(declStmt->getSolitaryDecl())->getType();
+    } else if (catchDecl) {
+      QualType t = catchDecl->getType();
       if (t == Context->getObjCIdType()) {
         buf += "1) { ";
         ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
@@ -1622,7 +1622,7 @@
       // Here we replace ") {" with "= _caught;" (which initializes and 
       // declares the @catch parameter).
       ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size());
-    } else if (!isa<NullStmt>(catchStmt)) {
+    } else {
       assert(false && "@catch rewrite bug");
     }
     // make sure all the catch bodies get rewritten!

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Mar  3 13:52:17 2009
@@ -31,6 +31,7 @@
   class ASTContext;
   class Expr;
   class Decl;
+  class ParmVarDecl;
   class QualType;
   class IdentifierInfo;
   class SourceManager;
@@ -1056,7 +1057,8 @@
 /// ObjCAtCatchStmt - This represents objective-c's @catch statement.
 class ObjCAtCatchStmt : public Stmt {
 private:
-  enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR };
+  enum { BODY, NEXT_CATCH, END_EXPR };
+  ParmVarDecl *ExceptionDecl;
   Stmt *SubExprs[END_EXPR];
   SourceLocation AtCatchLoc, RParenLoc;
 
@@ -1066,7 +1068,7 @@
 
 public:
   ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
-                  DeclStmt *catchVarStmtDecl, 
+                  ParmVarDecl *catchVarDecl, 
                   Stmt *atCatchStmt, Stmt *atCatchList);
   
   const Stmt *getCatchBody() const { return SubExprs[BODY]; }
@@ -1079,10 +1081,11 @@
     return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
   }
 
-  const DeclStmt *getCatchParamStmt() const { 
-    return static_cast<const DeclStmt*>(SubExprs[SELECTOR]); }
-  DeclStmt *getCatchParamStmt() { 
-    return static_cast<DeclStmt*>(SubExprs[SELECTOR]); 
+  const ParmVarDecl *getCatchParamDecl() const { 
+    return ExceptionDecl; 
+  }
+  ParmVarDecl *getCatchParamDecl() { 
+    return ExceptionDecl; 
   }
   
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -1091,7 +1094,7 @@
     return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 
   }
 
-  bool hasEllipsis() const { return getCatchParamStmt() == 0; }
+  bool hasEllipsis() const { return getCatchParamDecl() == 0; }
   
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == ObjCAtCatchStmtClass;

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Mar  3 13:52:17 2009
@@ -500,7 +500,7 @@
   // Objective-c statements
   virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
                                                 SourceLocation RParen,
-                                                StmtArg Parm, StmtArg Body,
+                                                DeclTy *Parm, StmtArg Body,
                                                 StmtArg CatchList) {
     return StmtEmpty();
   }

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Tue Mar  3 13:52:17 2009
@@ -180,10 +180,10 @@
 
 ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
                                  SourceLocation rparenloc,
-                                 DeclStmt *catchVarStmtDecl, Stmt *atCatchStmt,
+                                 ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
                                  Stmt *atCatchList)
 : Stmt(ObjCAtCatchStmtClass) {
-  SubExprs[SELECTOR] = catchVarStmtDecl;
+  ExceptionDecl = catchVarDecl;
   SubExprs[BODY] = atCatchStmt;
   SubExprs[NEXT_CATCH] = NULL;
   // FIXME: O(N^2) in number of catch blocks.

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Mar  3 13:52:17 2009
@@ -448,9 +448,9 @@
        catchStmt = 
          static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
     Indent() << "@catch(";
-    if (catchStmt->getCatchParamStmt()) {
-      if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt()))
-        PrintRawDeclStmt(DS);
+    if (catchStmt->getCatchParamDecl()) {
+      if (Decl *DS = catchStmt->getCatchParamDecl())
+        PrintRawDecl(DS);
     }
     OS << ")";
     if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) 

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Mar  3 13:52:17 2009
@@ -2014,30 +2014,28 @@
     for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
       llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch");
 
-      const DeclStmt *CatchParam = CatchStmt->getCatchParamStmt();
-      const VarDecl *VD = 0;
+      const ParmVarDecl *CatchParam = CatchStmt->getCatchParamDecl();
       const PointerType *PT = 0;
 
       // catch(...) always matches.
       if (!CatchParam) {
         AllMatched = true;
       } else {
-        VD = cast<VarDecl>(CatchParam->getSolitaryDecl());
-        PT = VD->getType()->getAsPointerType();
+        PT = CatchParam->getType()->getAsPointerType();
         
         // catch(id e) always matches. 
         // FIXME: For the time being we also match id<X>; this should
         // be rejected by Sema instead.
         if ((PT && CGF.getContext().isObjCIdStructType(PT->getPointeeType())) ||
-            VD->getType()->isObjCQualifiedIdType())
+            CatchParam->getType()->isObjCQualifiedIdType())
           AllMatched = true;
       }
       
       if (AllMatched) {   
         if (CatchParam) {
-          CGF.EmitStmt(CatchParam);
+          CGF.EmitLocalBlockVarDecl(*CatchParam);
           assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
-          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD));
+          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
         }
         
         CGF.EmitStmt(CatchStmt->getCatchBody());
@@ -2063,13 +2061,13 @@
       
       // Emit the @catch block.
       CGF.EmitBlock(MatchedBlock);
-      CGF.EmitStmt(CatchParam);
+      CGF.EmitLocalBlockVarDecl(*CatchParam);
       assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
 
       llvm::Value *Tmp = 
-        CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()), 
+        CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(CatchParam->getType()), 
                                   "tmp");
-      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(VD));
+      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
       
       CGF.EmitStmt(CatchStmt->getCatchBody());
       CGF.EmitBranchThroughCleanup(FinallyEnd);
@@ -4778,17 +4776,17 @@
   SelectorArgs.push_back(ObjCTypes.EHPersonalityPtr);
 
   // Construct the lists of (type, catch body) to handle.
-  llvm::SmallVector<std::pair<const DeclStmt*, const Stmt*>, 8> Handlers;
+  llvm::SmallVector<std::pair<const Decl*, const Stmt*>, 8> Handlers;
   bool HasCatchAll = false;
   if (isTry) {
     if (const ObjCAtCatchStmt* CatchStmt =
         cast<ObjCAtTryStmt>(S).getCatchStmts())  {
       for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
-        const DeclStmt *DS = CatchStmt->getCatchParamStmt();
-        Handlers.push_back(std::make_pair(DS, CatchStmt->getCatchBody()));
+        const Decl *CatchDecl = CatchStmt->getCatchParamDecl();
+        Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody()));
 
         // catch(...) always matches.
-        if (!DS) {
+        if (!CatchDecl) {
           // Use i8* null here to signal this is a catch all, not a cleanup.
           llvm::Value *Null = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
           SelectorArgs.push_back(Null);
@@ -4796,7 +4794,7 @@
           break;
         }
 
-        const VarDecl *VD = cast<VarDecl>(DS->getSolitaryDecl());
+        const VarDecl *VD = cast<VarDecl>(CatchDecl);
         if (CGF.getContext().isObjCIdType(VD->getType()) ||
             VD->getType()->isObjCQualifiedIdType()) {
           llvm::Value *IDEHType = 
@@ -4826,7 +4824,7 @@
   // We use a cleanup unless there was already a catch all.
   if (!HasCatchAll) {
     SelectorArgs.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
-    Handlers.push_back(std::make_pair((const DeclStmt*) 0, (const Stmt*) 0));
+    Handlers.push_back(std::make_pair((const Decl*) 0, (const Stmt*) 0));
   }
     
   llvm::Value *Selector = 
@@ -4834,7 +4832,7 @@
                            SelectorArgs.begin(), SelectorArgs.end(),
                            "selector");
   for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
-    const DeclStmt *CatchParam = Handlers[i].first;
+    const Decl *CatchParam = Handlers[i].first;
     const Stmt *CatchBody = Handlers[i].second;
 
     llvm::BasicBlock *Next = 0;
@@ -4871,10 +4869,10 @@
 
       // Bind the catch parameter if it exists.
       if (CatchParam) {
-        const VarDecl *VD = cast<VarDecl>(CatchParam->getSolitaryDecl());
+        const VarDecl *VD = dyn_cast<VarDecl>(CatchParam);
         ExcObject = CGF.Builder.CreateBitCast(ExcObject, 
                                               CGF.ConvertType(VD->getType()));
-        CGF.EmitStmt(CatchParam);
+        CGF.EmitLocalBlockVarDecl(*VD);
         CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(VD));
       }
 

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Mar  3 13:52:17 2009
@@ -1285,7 +1285,7 @@
 
     SourceLocation AtCatchFinallyLoc = ConsumeToken();
     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
-      OwningStmtResult FirstPart(Actions);
+      DeclTy *FirstPart = 0;
       ConsumeToken(); // consume catch
       if (Tok.is(tok::l_paren)) {
         ConsumeParen();
@@ -1294,17 +1294,14 @@
           DeclSpec DS;
           ParseDeclarationSpecifiers(DS);
           // For some odd reason, the name of the exception variable is
-          // optional. As a result, we need to use PrototypeContext.
-          Declarator DeclaratorInfo(DS, Declarator::PrototypeContext);
-          ParseDeclarator(DeclaratorInfo);
-          if (DeclaratorInfo.getIdentifier()) {
-            DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope,
-                                                          DeclaratorInfo, 0);
-            FirstPart =
-              Actions.ActOnDeclStmt(aBlockVarDecl,
-                                    DS.getSourceRange().getBegin(),
-                                    DeclaratorInfo.getSourceRange().getEnd());
-          }
+          // optional. As a result, we need to use "PrototypeContext", because 
+          // we must accept either 'declarator' or 'abstract-declarator' here.
+          Declarator ParmDecl(DS, Declarator::PrototypeContext);
+          ParseDeclarator(ParmDecl);
+
+          // Inform the actions module about the parameter declarator, so it
+          // gets added to the current scope.
+          FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
         } else
           ConsumeToken(); // consume '...'
         SourceLocation RParenLoc = ConsumeParen();
@@ -1317,7 +1314,7 @@
         if (CatchBody.isInvalid())
           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
         CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
-                        RParenLoc, move(FirstPart), move(CatchBody),
+                        RParenLoc, FirstPart, move(CatchBody),
                         move(CatchStmts));
       } else {
         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar  3 13:52:17 2009
@@ -1054,7 +1054,7 @@
 
   virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
                                                 SourceLocation RParen,
-                                                StmtArg Parm, StmtArg Body,
+                                                DeclTy *Parm, StmtArg Body,
                                                 StmtArg CatchList);
 
   virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=65964&r1=65963&r2=65964&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue Mar  3 13:52:17 2009
@@ -962,11 +962,11 @@
 
 Action::OwningStmtResult
 Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
-                           SourceLocation RParen, StmtArg Parm,
+                           SourceLocation RParen, DeclTy *Parm,
                            StmtArg Body, StmtArg catchList) {
   Stmt *CatchList = static_cast<Stmt*>(catchList.release());
   ObjCAtCatchStmt *CS = new (Context) ObjCAtCatchStmt(AtLoc, RParen,
-    static_cast<DeclStmt*>(Parm.release()), static_cast<Stmt*>(Body.release()),
+    static_cast<ParmVarDecl*>(Parm), static_cast<Stmt*>(Body.release()),
     CatchList);
   return Owned(CatchList ? CatchList : CS);
 }





More information about the cfe-commits mailing list