From 11fd5cf9fd813938a0d3140fb878851c22d67a65 Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 5 Sep 2018 19:02:00 +0000 Subject: [PATCH] Add -Wobjc-property-assign-on-object-type. This is a warning about using 'assign' instead of 'unsafe_unretained' in Objective-C property declarations. It's off by default because there isn't consensus in the Objective-C steering group that this is the right thing to do, but we're nonetheless okay with adding it because there's a substantial pool of Objective-C programmers who will appreciate the warning. Patch by Alfred Zien! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@341489 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 1 + include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ lib/Sema/SemaObjCProperty.cpp | 8 ++++++++ .../SemaObjC/property-assign-on-object-type.m | 19 +++++++++++++++++++ test/SemaObjC/property-in-class-extension-1.m | 4 ++-- 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 test/SemaObjC/property-assign-on-object-type.m diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 25c12445f7..4b77d08594 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -380,6 +380,7 @@ def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">; def BadFunctionCast : DiagGroup<"bad-function-cast">; def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">; def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; +def ObjCPropertyAssignOnObjectType : DiagGroup<"objc-property-assign-on-object-type">; def ObjCProtocolQualifiers : DiagGroup<"objc-protocol-qualifiers">; def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; def ObjCDesignatedInit : DiagGroup<"objc-designated-initializers">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 3bee16c2d4..77e050dc75 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1046,6 +1046,9 @@ def err_objc_property_attr_mutually_exclusive : Error< "property attributes '%0' and '%1' are mutually exclusive">; def err_objc_property_requires_object : Error< "property with '%0' attribute must be of object type">; +def warn_objc_property_assign_on_object : Warning< + "'assign' property of object type may become a dangling reference; consider using 'unsafe_unretained'">, + InGroup, DefaultIgnore; def warn_objc_property_no_assignment_attribute : Warning< "no 'assign', 'retain', or 'copy' attribute is specified - " "'assign' is assumed">, diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index ab7b83c4c3..d000027972 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -2557,6 +2557,14 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl, PropertyDecl->setInvalidDecl(); } + // Check for assign on object types. + if ((Attributes & ObjCDeclSpec::DQ_PR_assign) && + !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) && + PropertyTy->isObjCRetainableType() && + !PropertyTy->isObjCARCImplicitlyUnretainedType()) { + Diag(Loc, diag::warn_objc_property_assign_on_object); + } + // Check for more than one of { assign, copy, retain }. if (Attributes & ObjCDeclSpec::DQ_PR_assign) { if (Attributes & ObjCDeclSpec::DQ_PR_copy) { diff --git a/test/SemaObjC/property-assign-on-object-type.m b/test/SemaObjC/property-assign-on-object-type.m new file mode 100644 index 0000000000..6125bb21ed --- /dev/null +++ b/test/SemaObjC/property-assign-on-object-type.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wobjc-property-assign-on-object-type %s + +@interface Foo @end +@protocol Prot @end + +@interface Bar +@property(assign, readonly) Foo* o1; // expected-warning {{'assign' property of object type may become a dangling reference; consider using 'unsafe_unretained'}} +@property(unsafe_unretained, readonly) Foo* o2; + +@property(assign) Class classProperty; +@property(assign) Class classWithProtocolProperty; +@property(assign) int s1; +@property(assign) int* s2; +@end + +@interface Bar () +@property(readwrite) Foo* o1; +@property(readwrite) Foo* o2; +@end diff --git a/test/SemaObjC/property-in-class-extension-1.m b/test/SemaObjC/property-in-class-extension-1.m index 67b57e5fae..6215f70abc 100644 --- a/test/SemaObjC/property-in-class-extension-1.m +++ b/test/SemaObjC/property-in-class-extension-1.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-weak -verify -Weverything %s -// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-weak -fsyntax-only -verify -Weverything %s +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-weak -verify -Wproperty-attribute-mismatch %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fobjc-weak -fsyntax-only -verify -Wproperty-attribute-mismatch %s // rdar://12103400 @class NSString; -- 2.40.0