diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2017-04-06 12:53:43 +0000 |
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2017-04-06 12:53:43 +0000 |
| commit | b4791c7595eb1637c6371b1ec30756631c2c7f32 (patch) | |
| tree | fa11b0602ee05827d7a53c2ec57cbf0b4f7418e4 /clang/lib/Sema | |
| parent | e228f68811ffe816faaa892b27dafb788393aba8 (diff) | |
| download | bcm5719-llvm-b4791c7595eb1637c6371b1ec30756631c2c7f32.tar.gz bcm5719-llvm-b4791c7595eb1637c6371b1ec30756631c2c7f32.zip | |
Fix lambda to block conversion in C++17 by avoiding copy elision for the
lambda capture used by the created block
The commit r288866 introduced guaranteed copy elision to C++ 17. This
unfortunately broke the lambda to block conversion in C++17 (the compiler
crashes when performing IRGen). This commit fixes the conversion by avoiding
copy elision for the capture that captures the lambda that's used in the block
created by the lambda to block conversion process.
rdar://31385153
Differential Revision: https://reviews.llvm.org/D31669
llvm-svn: 299646
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 7 |
2 files changed, 20 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index b11769bf428..b6f799b6211 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -950,6 +950,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity, case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_Binding: llvm_unreachable("unexpected braced scalar init"); } @@ -2934,6 +2935,7 @@ DeclarationName InitializedEntity::getName() const { case EK_VectorElement: case EK_ComplexElement: case EK_BlockElement: + case EK_LambdaToBlockConversionBlockElement: case EK_CompoundLiteralInit: case EK_RelatedResult: return DeclarationName(); @@ -2963,6 +2965,7 @@ ValueDecl *InitializedEntity::getDecl() const { case EK_VectorElement: case EK_ComplexElement: case EK_BlockElement: + case EK_LambdaToBlockConversionBlockElement: case EK_LambdaCapture: case EK_CompoundLiteralInit: case EK_RelatedResult: @@ -2992,6 +2995,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_VectorElement: case EK_ComplexElement: case EK_BlockElement: + case EK_LambdaToBlockConversionBlockElement: case EK_LambdaCapture: case EK_RelatedResult: break; @@ -3025,6 +3029,9 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { case EK_VectorElement: OS << "VectorElement " << Index; break; case EK_ComplexElement: OS << "ComplexElement " << Index; break; case EK_BlockElement: OS << "Block"; break; + case EK_LambdaToBlockConversionBlockElement: + OS << "Block (lambda)"; + break; case EK_LambdaCapture: OS << "LambdaCapture "; OS << DeclarationName(Capture.VarID); @@ -3622,9 +3629,13 @@ static void TryConstructorInitialization(Sema &S, // destination object. // Per DR (no number yet), this does not apply when initializing a base // class or delegating to another constructor from a mem-initializer. + // ObjC++: Lambda captured by the block in the lambda to block conversion + // should avoid copy elision. if (S.getLangOpts().CPlusPlus1z && Entity.getKind() != InitializedEntity::EK_Base && Entity.getKind() != InitializedEntity::EK_Delegating && + Entity.getKind() != + InitializedEntity::EK_LambdaToBlockConversionBlockElement && UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isRValue() && S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) { // Convert qualifications if necessary. @@ -5488,6 +5499,7 @@ getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) { case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_LambdaCapture: case InitializedEntity::EK_CompoundLiteralInit: return Sema::AA_Initializing; @@ -5511,6 +5523,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_Exception: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_LambdaCapture: case InitializedEntity::EK_CompoundLiteralInit: return false; @@ -5537,6 +5550,7 @@ static bool shouldDestroyEntity(const InitializedEntity &Entity) { case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_LambdaCapture: return false; @@ -5584,6 +5598,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity, case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_CompoundLiteralInit: case InitializedEntity::EK_RelatedResult: return Initializer->getLocStart(); @@ -6021,6 +6036,7 @@ InitializedEntityOutlivesFullExpression(const InitializedEntity &Entity) { case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_ComplexElement: // Could not determine what the full initialization is. Assume it might not // outlive the full-expression. @@ -6109,6 +6125,7 @@ static const InitializedEntity *getEntityForTemporaryLifetimeExtension( return FallbackDecl; case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_LambdaCapture: case InitializedEntity::EK_Exception: case InitializedEntity::EK_VectorElement: diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 2b13f2af685..7a9a8ff911a 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1649,10 +1649,9 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, CallOperator->markUsed(Context); ExprResult Init = PerformCopyInitialization( - InitializedEntity::InitializeBlock(ConvLocation, - Src->getType(), - /*NRVO=*/false), - CurrentLocation, Src); + InitializedEntity::InitializeLambdaToBlock(ConvLocation, Src->getType(), + /*NRVO=*/false), + CurrentLocation, Src); if (!Init.isInvalid()) Init = ActOnFinishFullExpr(Init.get()); |

