aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaObjCProperty.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-05-15 22:37:04 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-05-15 22:37:04 +0000
commit9abf88c9286d7465ce18285f87bb302f588b59fc (patch)
tree6190ba9e248855387d018ddb69ae6339ca52d1a5 /lib/Sema/SemaObjCProperty.cpp
parent5ec351c9507f12d5bede569c51d5257fad167134 (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.cpp47
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;
}