summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp23
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);
OpenPOWER on IntegriCloud