aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaObjCProperty.cpp34
-rw-r--r--test/SemaObjC/property-ivar-mismatch.m12
2 files changed, 30 insertions, 16 deletions
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 5a98077bd7..e826b47784 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -658,6 +658,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
}
ObjCIvarDecl *Ivar = 0;
bool CompleteTypeErr = false;
+ bool compat = true;
// Check that we have a valid, previously declared ivar for @synthesize
if (Synthesize) {
// @synthesize
@@ -773,8 +774,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
QualType IvarType = Context.getCanonicalType(Ivar->getType());
// Check that type of property and its ivar are type compatible.
- if (Context.getCanonicalType(PropertyIvarType) != IvarType) {
- bool compat = false;
+ if (!Context.hasSameType(PropertyIvarType, IvarType)) {
+ compat = false;
if (isa<ObjCObjectPointerType>(PropertyIvarType)
&& isa<ObjCObjectPointerType>(IvarType))
compat =
@@ -794,19 +795,20 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
// Note! I deliberately want it to fall thru so, we have a
// a property implementation and to avoid future warnings.
}
-
- // FIXME! Rules for properties are somewhat different that those
- // for assignments. Use a new routine to consolidate all cases;
- // specifically for property redeclarations as well as for ivars.
- QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType();
- QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
- if (lhsType != rhsType &&
- lhsType->isArithmeticType()) {
- Diag(PropertyDiagLoc, diag::error_property_ivar_type)
- << property->getDeclName() << PropType
- << Ivar->getDeclName() << IvarType;
- Diag(Ivar->getLocation(), diag::note_ivar_decl);
- // Fall thru - see previous comment
+ else {
+ // FIXME! Rules for properties are somewhat different that those
+ // for assignments. Use a new routine to consolidate all cases;
+ // specifically for property redeclarations as well as for ivars.
+ QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType();
+ QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
+ if (lhsType != rhsType &&
+ lhsType->isArithmeticType()) {
+ Diag(PropertyDiagLoc, diag::error_property_ivar_type)
+ << property->getDeclName() << PropType
+ << Ivar->getDeclName() << IvarType;
+ Diag(Ivar->getLocation(), diag::note_ivar_decl);
+ // Fall thru - see previous comment
+ }
}
// __weak is explicit. So it works on Canonical type.
if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
@@ -840,7 +842,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
: ObjCPropertyImplDecl::Dynamic),
Ivar, PropertyIvarLoc);
- if (CompleteTypeErr)
+ if (CompleteTypeErr || !compat)
PIDecl->setInvalidDecl();
if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
diff --git a/test/SemaObjC/property-ivar-mismatch.m b/test/SemaObjC/property-ivar-mismatch.m
index 6abd6e662d..a0d1c9da7b 100644
--- a/test/SemaObjC/property-ivar-mismatch.m
+++ b/test/SemaObjC/property-ivar-mismatch.m
@@ -12,3 +12,15 @@
@synthesize prop = ivar; // expected-error {{type of property 'prop' ('int') does not match type of ivar 'ivar' ('char')}}
@end
+
+@interface Test5
+{
+ void * _P; // expected-note {{ivar is declared here}}
+}
+@property int P;
+@end
+
+@implementation Test5
+@synthesize P=_P; // expected-error {{ype of property 'P' ('int') does not match type of ivar '_P' ('void *')}}
+@end
+