[cfe-commits] r151131 - in /cfe/trunk: include/clang/AST/ lib/AST/ lib/CodeGen/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Core/ test/CXX/expr/expr.prim/expr.prim.lambda/ test/PCH/

Douglas Gregor dgregor at apple.com
Tue Feb 21 21:02:48 PST 2012


Author: dgregor
Date: Tue Feb 21 23:02:47 2012
New Revision: 151131

URL: http://llvm.org/viewvc/llvm-project?rev=151131&view=rev
Log:
Generate an AST for the conversion from a lambda closure type to a
block pointer that returns a block literal which captures (by copy)
the lambda closure itself. Some aspects of the block literal are left
unspecified, namely the capture variable (which doesn't actually
exist) and the body (which will be filled in by IRgen because it can't
be written as an AST).

Because we're switching to this model, this patch also eliminates
tracking the copy-initialization expression for the block capture of
the conversion function, since that information is now embedded in the
synthesized block literal. -1 side tables FTW.


Added:
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
      - copied unchanged from r151057, cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp
    cfe/trunk/test/PCH/cxx11-lambdas.mm
      - copied unchanged from r151057, cfe/trunk/test/PCH/cxx11-lambdas.cpp
Removed:
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp
    cfe/trunk/test/PCH/cxx11-lambdas.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/OperationKinds.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Feb 21 23:02:47 2012
@@ -323,12 +323,6 @@
   typedef UsuallyTinyPtrVector<const CXXMethodDecl> CXXMethodVector;
   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
 
-  /// \brief Mapping from lambda-to-block-pointer conversion functions to the
-  /// expression used to copy the lambda object.
-  llvm::DenseMap<const CXXConversionDecl *, Expr *> LambdaBlockPointerInits;
-  
-  friend class CXXConversionDecl;
-  
   /// \brief Mapping from each declaration context to its corresponding lambda 
   /// mangling context.
   llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Feb 21 23:02:47 2012
@@ -2261,15 +2261,6 @@
   /// a lambda closure type to a block pointer.
   bool isLambdaToBlockPointerConversion() const;
   
-  /// \brief For an implicit conversion function that converts a lambda
-  /// closure type to a block pointer, retrieve the expression used to
-  /// copy the closure object into the block.
-  Expr *getLambdaToBlockPointerCopyInit() const;
-  
-  /// \brief Set the copy-initialization expression to be used when converting
-  /// a lambda object to a block pointer.
-  void setLambdaToBlockPointerCopyInit(Expr *Init);
-  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const CXXConversionDecl *D) { return true; }

Modified: cfe/trunk/include/clang/AST/OperationKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.h?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OperationKinds.h (original)
+++ cfe/trunk/include/clang/AST/OperationKinds.h Tue Feb 21 23:02:47 2012
@@ -281,7 +281,14 @@
   /// \brief Converts from _Atomic(T) to T.
   CK_AtomicToNonAtomic,
   /// \brief Converts from T to _Atomic(T).
-  CK_NonAtomicToAtomic
+  CK_NonAtomicToAtomic,
+  
+  /// \brief Causes a block literal to by copied to the heap and then 
+  /// autoreleased.
+  ///
+  /// This particular cast kind is used for the conversion from a C++11
+  /// lambda expression to a block pointer.
+  CK_CopyAndAutoreleaseBlockObject
 };
 
 #define CK_Invalid ((CastKind) -1)

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Feb 21 23:02:47 2012
@@ -1770,16 +1770,6 @@
          getConversionType()->isBlockPointerType();
 }
 
-Expr *CXXConversionDecl::getLambdaToBlockPointerCopyInit() const {
-  assert(isLambdaToBlockPointerConversion());
-  return getASTContext().LambdaBlockPointerInits[this];
-}
-
-void CXXConversionDecl::setLambdaToBlockPointerCopyInit(Expr *Init) {
-  assert(isLambdaToBlockPointerConversion());
-  getASTContext().LambdaBlockPointerInits[this] = Init;
-}
-
 void LinkageSpecDecl::anchor() { }
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Feb 21 23:02:47 2012
@@ -1076,6 +1076,11 @@
            !getSubExpr()->getType()->isBlockPointerType());
     goto CheckNoBasePath;
 
+  case CK_CopyAndAutoreleaseBlockObject:
+    assert(getType()->isBlockPointerType());
+    assert(getSubExpr()->getType()->isBlockPointerType());
+    goto CheckNoBasePath;
+      
   // These should not have an inheritance path.
   case CK_Dynamic:
   case CK_ToUnion:
@@ -1231,6 +1236,8 @@
     return "AtomicToNonAtomic";
   case CK_NonAtomicToAtomic:
     return "NonAtomicToAtomic";
+  case CK_CopyAndAutoreleaseBlockObject:
+    return "CopyAndAutoreleaseBlockObject";
   }
 
   llvm_unreachable("Unhandled cast kind!");

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Feb 21 23:02:47 2012
@@ -5209,6 +5209,7 @@
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
+  case CK_CopyAndAutoreleaseBlockObject:
     return Error(E);
 
   case CK_UserDefinedConversion:
@@ -5684,6 +5685,7 @@
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
+  case CK_CopyAndAutoreleaseBlockObject:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Tue Feb 21 23:02:47 2012
@@ -516,7 +516,8 @@
     OS << "(capture ";
     if (i->isByRef()) OS << "byref ";
     if (i->isNested()) OS << "nested ";
-    DumpDeclRef(i->getVariable());
+    if (i->getVariable())
+      DumpDeclRef(i->getVariable());
     if (i->hasCopyExpr()) DumpSubTree(i->getCopyExpr());
     OS << ")";
   }

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Feb 21 23:02:47 2012
@@ -2096,7 +2096,8 @@
   case CK_ARCProduceObject:
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
-  case CK_ARCExtendBlockObject: {
+  case CK_ARCExtendBlockObject: 
+  case CK_CopyAndAutoreleaseBlockObject: {
     // These casts only produce lvalues when we're binding a reference to a 
     // temporary realized from a (converted) pure rvalue. Emit the expression
     // as a value, copy it into a temporary, and return an lvalue referring to

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Feb 21 23:02:47 2012
@@ -614,6 +614,7 @@
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
+  case CK_CopyAndAutoreleaseBlockObject:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }

Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Tue Feb 21 23:02:47 2012
@@ -413,6 +413,7 @@
   case CK_ARCConsumeObject:
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
+  case CK_CopyAndAutoreleaseBlockObject:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Feb 21 23:02:47 2012
@@ -636,6 +636,7 @@
     case CK_ARCConsumeObject:
     case CK_ARCReclaimReturnedObject:
     case CK_ARCExtendBlockObject:
+    case CK_CopyAndAutoreleaseBlockObject:
       return 0;
 
     // These don't need to be handled here because Evaluate knows how to

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Feb 21 23:02:47 2012
@@ -1148,6 +1148,10 @@
   case CK_ARCExtendBlockObject:
     return CGF.EmitARCExtendBlockObject(E);
 
+  case CK_CopyAndAutoreleaseBlockObject:
+    CGF.ErrorUnsupported(E, "copy/autorelease block object");
+    return 0;
+      
   case CK_FloatingRealToComplex:
   case CK_FloatingComplexCast:
   case CK_IntegralRealToComplex:

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Feb 21 23:02:47 2012
@@ -3000,9 +3000,11 @@
     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
     QualType T = SubExpr->getType();
 
-    if (SubExpr->getType()->isPointerType() ||
-        SubExpr->getType()->isBlockPointerType() ||
-        SubExpr->getType()->isObjCQualifiedIdType())
+    if (cast<CastExpr>(E)->getCastKind() == CK_CopyAndAutoreleaseBlockObject)
+      return 0;
+    else if (SubExpr->getType()->isPointerType() ||
+             SubExpr->getType()->isBlockPointerType() ||
+             SubExpr->getType()->isObjCQualifiedIdType())
       return EvalAddr(SubExpr, refVars);
     else if (T->isArrayType())
       return EvalVal(SubExpr, refVars);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Feb 21 23:02:47 2012
@@ -8755,9 +8755,9 @@
 /// \brief Mark the call operator of the given lambda closure type as "used".
 static void markLambdaCallOperatorUsed(Sema &S, CXXRecordDecl *Lambda) {
   CXXMethodDecl *CallOperator 
-  = cast<CXXMethodDecl>(
-      *Lambda->lookup(
-        S.Context.DeclarationNames.getCXXOperatorName(OO_Call)).first);
+    = cast<CXXMethodDecl>(
+        *Lambda->lookup(
+          S.Context.DeclarationNames.getCXXOperatorName(OO_Call)).first);
   CallOperator->setReferenced();
   CallOperator->setUsed();
 }
@@ -8805,14 +8805,21 @@
        SourceLocation CurrentLocation,
        CXXConversionDecl *Conv) 
 {
+  CXXRecordDecl *Lambda = Conv->getParent();
+  
   // Make sure that the lambda call operator is marked used.
-  markLambdaCallOperatorUsed(*this, Conv->getParent());
+  CXXMethodDecl *CallOperator 
+    = cast<CXXMethodDecl>(
+        *Lambda->lookup(
+          Context.DeclarationNames.getCXXOperatorName(OO_Call)).first);
+  CallOperator->setReferenced();
+  CallOperator->setUsed();
   Conv->setUsed();
   
   ImplicitlyDefinedFunctionScope Scope(*this, Conv);
   DiagnosticErrorTrap Trap(Diags);
   
-  // Copy-initialize the lambda object as needed to capture
+  // Copy-initialize the lambda object as needed to capture it.
   Expr *This = ActOnCXXThis(CurrentLocation).take();
   Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take();
   ExprResult Init = PerformCopyInitialization(
@@ -8823,16 +8830,78 @@
   if (!Init.isInvalid())
     Init = ActOnFinishFullExpr(Init.take());
   
-  if (!Init.isInvalid())
-    Conv->setLambdaToBlockPointerCopyInit(Init.take());
-  else {
+  if (Init.isInvalid()) {
     Diag(CurrentLocation, diag::note_lambda_to_block_conv);
+    Conv->setInvalidDecl();
+    return;
   }
   
-  // Introduce a bogus body, which IR generation will override anyway.
-  Conv->setBody(new (Context) CompoundStmt(Context, 0, 0, Conv->getLocation(),
+  // Create the new block to be returned.
+  BlockDecl *Block = BlockDecl::Create(Context, Conv, Conv->getLocation());
+  
+  // Set the type information.
+  Block->setSignatureAsWritten(CallOperator->getTypeSourceInfo());
+  Block->setIsVariadic(CallOperator->isVariadic());
+  Block->setBlockMissingReturnType(false);
+  
+  // Add parameters.
+  SmallVector<ParmVarDecl *, 4> BlockParams;
+  for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) {
+    ParmVarDecl *From = CallOperator->getParamDecl(I);
+    BlockParams.push_back(ParmVarDecl::Create(Context, Block,
+                                              From->getLocStart(),
+                                              From->getLocation(),
+                                              From->getIdentifier(),
+                                              From->getType(),
+                                              From->getTypeSourceInfo(),
+                                              From->getStorageClass(),
+                                            From->getStorageClassAsWritten(),
+                                              /*DefaultArg=*/0));
+  }
+  Block->setParams(BlockParams);
+  
+  // Add capture. The capture is uses a fake (NULL) variable, since we don't
+  // actually want to have to name a capture variable. However, the 
+  // initializer copy-initializes the lambda object.
+  BlockDecl::Capture Capture(/*Variable=*/0, /*ByRef=*/false, /*Nested=*/false,
+                             /*Copy=*/Init.take());
+  Block->setCaptures(Context, &Capture, &Capture + 1, 
+                     /*CapturesCXXThis=*/false);
+  
+  // Add a fake function body to the block. IR generation is responsible
+  // for filling in the actual body, which cannot be expressed as an AST.
+  Block->setBody(new (Context) CompoundStmt(Context, 0, 0, 
+                                            Conv->getLocation(),
+                                            Conv->getLocation()));
+
+  // Create the block literal expression.
+  Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType());
+  ExprCleanupObjects.push_back(Block);
+  ExprNeedsCleanups = true;
+
+  // If we're not under ARC, make sure we still get the _Block_copy/autorelease
+  // behavior.
+  if (!getLangOptions().ObjCAutoRefCount)
+    BuildBlock = ImplicitCastExpr::Create(Context, BuildBlock->getType(),
+                                          CK_CopyAndAutoreleaseBlockObject,
+                                          BuildBlock, 0, VK_RValue);
+  
+  // Create the return statement that returns the block from the conversion
+  // function.
+  StmtResult Return = ActOnReturnStmt(Conv->getLocation(), BuildBlock);
+  if (Return.isInvalid()) {
+    Diag(CurrentLocation, diag::note_lambda_to_block_conv);
+    Conv->setInvalidDecl();
+    return;
+  }
+
+  // Set the body of the conversion function.
+  Stmt *ReturnS = Return.take();
+  Conv->setBody(new (Context) CompoundStmt(Context, &ReturnS, 1, 
+                                           Conv->getLocation(), 
                                            Conv->getLocation()));
   
+  // We're done; notify the mutation listener, if any.
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(Conv);
   }

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Tue Feb 21 23:02:47 2012
@@ -643,7 +643,7 @@
     //   non-explicit const conversion function to a block pointer having the
     //   same parameter and return types as the closure type's function call
     //   operator.
-    if (getLangOptions().Blocks)
+    if (getLangOptions().Blocks && getLangOptions().ObjC1)
       addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
     
     // Finalize the lambda class.

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Feb 21 23:02:47 2012
@@ -1213,8 +1213,6 @@
 void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
   VisitCXXMethodDecl(D);
   D->IsExplicitSpecified = Record[Idx++];
-  if (D->isLambdaToBlockPointerConversion())
-    D->setLambdaToBlockPointerCopyInit(Reader.ReadExpr(F));
 }
 
 void ASTDeclReader::VisitImportDecl(ImportDecl *D) {

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Feb 21 23:02:47 2012
@@ -965,8 +965,6 @@
 void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
   VisitCXXMethodDecl(D);
   Record.push_back(D->IsExplicitSpecified);
-  if (D->isLambdaToBlockPointerConversion())
-    Writer.AddStmt(D->getLambdaToBlockPointerCopyInit());
   Code = serialization::DECL_CXX_CONVERSION;
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=151131&r1=151130&r2=151131&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Tue Feb 21 23:02:47 2012
@@ -218,6 +218,7 @@
       case CK_ARCConsumeObject:
       case CK_ARCReclaimReturnedObject:
       case CK_ARCExtendBlockObject: // Fall-through.
+      case CK_CopyAndAutoreleaseBlockObject:
         // The analyser can ignore atomic casts for now, although some future
         // checkers may want to make certain that you're not modifying the same
         // value through atomic and nonatomic pointers.

Removed: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp?rev=151130&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp (removed)
@@ -1,57 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -fblocks %s -verify
-
-void block_capture_errors() {
-  __block int var; // expected-note 2{{'var' declared here}}
-  (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
-
-  (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
-}
-
-void conversion_to_block(int captured) {
-  int (^b1)(int) = [=](int x) { return x + captured; };
-
-  const auto lambda = [=](int x) { return x + captured; };
-  int (^b2)(int) = lambda;
-}
-
-template<typename T>
-class ConstCopyConstructorBoom {
-public:
-  ConstCopyConstructorBoom(ConstCopyConstructorBoom&);
-
-  ConstCopyConstructorBoom(const ConstCopyConstructorBoom&) {
-    T *ptr = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}
-  }
-
-  void foo() const;
-};
-
-void conversion_to_block_init(ConstCopyConstructorBoom<int> boom,
-                              ConstCopyConstructorBoom<float> boom2) {
-  const auto& lambda1([=] { boom.foo(); }); // okay
-
-  const auto& lambda2([=] { boom2.foo(); }); // expected-note{{in instantiation of member function}}
-  void (^block)(void) = lambda2;
-}
-
-
-void nesting() {
-  int array[7]; // expected-note 2{{'array' declared here}}
-  [=] () mutable {
-    [&] {
-      ^ {
-        int i = array[2];
-        i += array[3];
-      }();
-    }();
-  }();
-
-  [&] {
-    [=] () mutable {
-      ^ {
-        int i = array[2]; // expected-error{{cannot refer to declaration with an array type inside block}}
-        i += array[3]; // expected-error{{cannot refer to declaration with an array type inside block}}
-      }();
-    }();
-  }();
-}

Removed: cfe/trunk/test/PCH/cxx11-lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx11-lambdas.cpp?rev=151130&view=auto
==============================================================================
--- cfe/trunk/test/PCH/cxx11-lambdas.cpp (original)
+++ cfe/trunk/test/PCH/cxx11-lambdas.cpp (removed)
@@ -1,48 +0,0 @@
-// RUN: %clang_cc1 -pedantic-errors -fblocks -std=c++11 -emit-pch %s -o %t-cxx11
-// RUN: %clang_cc1 -ast-print -pedantic-errors -fblocks -std=c++11 -include-pch %t-cxx11  %s | FileCheck -check-prefix=CHECK-PRINT %s
-
-#ifndef HEADER_INCLUDED
-
-#define HEADER_INCLUDED
-template<typename T>
-T add_slowly(const T& x, const T &y) {
-  return [=, &y] { return x + y; }();
-};
-
-inline int add_int_slowly_twice(int x, int y) {
-  int i = add_slowly(x, y);
-  auto lambda = [&](int z) { return x + z; };
-  return i + lambda(y);
-}
-
-inline int sum_array(int n) {
-  int array[5] = { 1, 2, 3, 4, 5};
-  auto lambda = [=](int N) -> int {
-    int sum = 0;
-    for (unsigned I = 0; I < N; ++I)
-      sum += array[N];
-    return sum;
-  };
-
-  return lambda(n);
-}
-
-inline int to_block_pointer(int n) {
-  auto lambda = [=](int m) { return n + m; };
-  int (^block)(int) = lambda;
-  return block(17);
-}
-
-#else
-
-// CHECK-PRINT: T add_slowly
-// CHECK-PRINT: return [=, &y]
-template float add_slowly(const float&, const float&);
-
-int add(int x, int y) {
-  return add_int_slowly_twice(x, y) + sum_array(4) + to_block_pointer(5);
-}
-
-// CHECK-PRINT: inline int add_int_slowly_twice 
-// CHECK-PRINT: lambda = [&] (int z)
-#endif





More information about the cfe-commits mailing list