From c6ac9c3d754f91d27b1734965e5f1a8e542e8f40 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 4 Feb 2011 18:33:18 +0000 Subject: [PATCH] Assert during instantiation of blocks that we've captured everything that we captured in the dependent case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124887 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/TreeTransform.h | 100 ++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 3f8d3e5ec4..472e281553 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -7136,70 +7136,92 @@ TreeTransform::TransformShuffleVectorExpr(ShuffleVectorExpr *E) { template ExprResult TreeTransform::TransformBlockExpr(BlockExpr *E) { - SourceLocation CaretLoc(E->getExprLoc()); + BlockDecl *oldBlock = E->getBlockDecl(); - SemaRef.ActOnBlockStart(CaretLoc, /*Scope=*/0); - BlockScopeInfo *CurBlock = SemaRef.getCurBlock(); - CurBlock->TheDecl->setIsVariadic(E->getBlockDecl()->isVariadic()); - llvm::SmallVector Params; - llvm::SmallVector ParamTypes; + SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/0); + BlockScopeInfo *blockScope = SemaRef.getCurBlock(); + + blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic()); + llvm::SmallVector params; + llvm::SmallVector paramTypes; // Parameter substitution. - BlockDecl *BD = E->getBlockDecl(); - if (getDerived().TransformFunctionTypeParams(E->getLocStart(), - BD->param_begin(), - BD->param_size(), 0, ParamTypes, - &Params)) + if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(), + oldBlock->param_begin(), + oldBlock->param_size(), + 0, paramTypes, ¶ms)) return true; - - - const FunctionType *BExprFunctionType = E->getFunctionType(); - QualType BExprResultType = BExprFunctionType->getResultType(); - if (!BExprResultType.isNull()) { - if (!BExprResultType->isDependentType()) - CurBlock->ReturnType = BExprResultType; - else if (BExprResultType != SemaRef.Context.DependentTy) - CurBlock->ReturnType = getDerived().TransformType(BExprResultType); + + const FunctionType *exprFunctionType = E->getFunctionType(); + QualType exprResultType = exprFunctionType->getResultType(); + if (!exprResultType.isNull()) { + if (!exprResultType->isDependentType()) + blockScope->ReturnType = exprResultType; + else if (exprResultType != getSema().Context.DependentTy) + blockScope->ReturnType = getDerived().TransformType(exprResultType); } // If the return type has not been determined yet, leave it as a dependent // type; it'll get set when we process the body. - if (CurBlock->ReturnType.isNull()) - CurBlock->ReturnType = getSema().Context.DependentTy; + if (blockScope->ReturnType.isNull()) + blockScope->ReturnType = getSema().Context.DependentTy; // Don't allow returning a objc interface by value. - if (CurBlock->ReturnType->isObjCObjectType()) { - getSema().Diag(E->getLocStart(), + if (blockScope->ReturnType->isObjCObjectType()) { + getSema().Diag(E->getCaretLocation(), diag::err_object_cannot_be_passed_returned_by_value) - << 0 << CurBlock->ReturnType; + << 0 << blockScope->ReturnType; return ExprError(); } - QualType FunctionType = getDerived().RebuildFunctionProtoType( - CurBlock->ReturnType, - ParamTypes.data(), - ParamTypes.size(), - BD->isVariadic(), + QualType functionType = getDerived().RebuildFunctionProtoType( + blockScope->ReturnType, + paramTypes.data(), + paramTypes.size(), + oldBlock->isVariadic(), 0, RQ_None, - BExprFunctionType->getExtInfo()); - CurBlock->FunctionType = FunctionType; + exprFunctionType->getExtInfo()); + blockScope->FunctionType = functionType; // Set the parameters on the block decl. - if (!Params.empty()) - CurBlock->TheDecl->setParams(Params.data(), Params.size()); + if (!params.empty()) + blockScope->TheDecl->setParams(params.data(), params.size()); // If the return type wasn't explicitly set, it will have been marked as a // dependent type (DependentTy); clear out the return type setting so // we will deduce the return type when type-checking the block's body. - if (CurBlock->ReturnType == getSema().Context.DependentTy) - CurBlock->ReturnType = QualType(); + if (blockScope->ReturnType == getSema().Context.DependentTy) + blockScope->ReturnType = QualType(); // Transform the body - StmtResult Body = getDerived().TransformStmt(E->getBody()); - if (Body.isInvalid()) + StmtResult body = getDerived().TransformStmt(E->getBody()); + if (body.isInvalid()) return ExprError(); - return SemaRef.ActOnBlockStmtExpr(CaretLoc, Body.get(), /*Scope=*/0); +#ifndef NDEBUG + // In builds with assertions, make sure that we captured everything we + // captured before. + + if (oldBlock->capturesCXXThis()) assert(blockScope->CapturesCXXThis); + + for (BlockDecl::capture_iterator i = oldBlock->capture_begin(), + e = oldBlock->capture_end(); i != e; ++i) { + VarDecl *oldCapture = *i; + + // Ignore parameter packs. + if (isa(oldCapture) && + cast(oldCapture)->isParameterPack()) + continue; + + VarDecl *newCapture = + cast(getDerived().TransformDecl(E->getCaretLocation(), + oldCapture)); + assert(blockScope->Captures.count(newCapture)); + } +#endif + + return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(), + /*Scope=*/0); } template -- 2.40.0