diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 388420cc1ba..be97e27ae6d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13603,11 +13603,28 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, } // Warn about implicitly autoreleasing indirect parameters captured by blocks. - if (auto *PT = dyn_cast<PointerType>(CaptureType)) { + if (const auto *PT = CaptureType->getAs<PointerType>()) { + // This function finds out whether there is an AttributedType of kind + // attr_objc_ownership in Ty. The existence of AttributedType of kind + // attr_objc_ownership implies __autoreleasing was explicitly specified + // rather than being added implicitly by the compiler. + auto IsObjCOwnershipAttributedType = [](QualType Ty) { + while (const auto *AttrTy = Ty->getAs<AttributedType>()) { + if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership) + return true; + + // Peel off AttributedTypes that are not of kind objc_ownership. + Ty = AttrTy->getModifiedType(); + } + + return false; + }; + QualType PointeeTy = PT->getPointeeType(); - if (isa<ObjCObjectPointerType>(PointeeTy.getCanonicalType()) && + + if (PointeeTy->getAs<ObjCObjectPointerType>() && PointeeTy.getObjCLifetime() == Qualifiers::OCL_Autoreleasing && - !isa<AttributedType>(PointeeTy)) { + !IsObjCOwnershipAttributedType(PointeeTy)) { if (BuildAndDiagnose) { SourceLocation VarLoc = Var->getLocation(); S.Diag(Loc, diag::warn_block_capture_autoreleasing); |

