diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-05-15 22:37:04 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-05-15 22:37:04 +0000 |
commit | 9abf88c9286d7465ce18285f87bb302f588b59fc (patch) | |
tree | 6190ba9e248855387d018ddb69ae6339ca52d1a5 /lib/Sema/SemaObjCProperty.cpp | |
parent | 5ec351c9507f12d5bede569c51d5257fad167134 (diff) |
objective-c: perform strict type checking on property
type and its accessor type and issue error if types
are incompatible, instead of crashing in IRgen.
// rdar://1105153
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156871 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaObjCProperty.cpp')
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index e826b47784..f42259c686 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1050,21 +1050,42 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, ObjCMethodDecl *GetterMethod, SourceLocation Loc) { - if (GetterMethod && - !Context.hasSameType(GetterMethod->getResultType().getNonReferenceType(), - property->getType().getNonReferenceType())) { - AssignConvertType result = Incompatible; - if (property->getType()->isObjCObjectPointerType()) - result = CheckAssignmentConstraints(Loc, GetterMethod->getResultType(), - property->getType()); - if (result != Compatible) { - Diag(Loc, diag::warn_accessor_property_type_mismatch) - << property->getDeclName() - << GetterMethod->getSelector(); - Diag(GetterMethod->getLocation(), diag::note_declared_at); - return true; + if (!GetterMethod) + return false; + QualType GetterType = GetterMethod->getResultType().getNonReferenceType(); + QualType PropertyIvarType = property->getType().getNonReferenceType(); + bool compat = Context.hasSameType(PropertyIvarType, GetterType); + if (!compat) { + if (isa<ObjCObjectPointerType>(PropertyIvarType) && + isa<ObjCObjectPointerType>(GetterType)) + compat = + Context.canAssignObjCInterfaces( + PropertyIvarType->getAs<ObjCObjectPointerType>(), + GetterType->getAs<ObjCObjectPointerType>()); + else if (CheckAssignmentConstraints(Loc, PropertyIvarType, GetterType) + != Compatible) { + Diag(Loc, diag::error_property_accessor_type) + << property->getDeclName() << PropertyIvarType + << GetterMethod->getSelector() << GetterType; + Diag(GetterMethod->getLocation(), diag::note_declared_at); + return true; + } else { + compat = true; + QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); + QualType rhsType =Context.getCanonicalType(GetterType).getUnqualifiedType(); + if (lhsType != rhsType && lhsType->isArithmeticType()) + compat = false; } } + + if (!compat) { + Diag(Loc, diag::warn_accessor_property_type_mismatch) + << property->getDeclName() + << GetterMethod->getSelector(); + Diag(GetterMethod->getLocation(), diag::note_declared_at); + return true; + } + return false; } |