[clang] fda47db - [Clang][Sema] Fix attribute mismatch warning for ObjC class properties
Egor Zhdan via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 11 04:31:58 PST 2022
Author: Egor Zhdan
Date: 2022-01-11T12:10:18Z
New Revision: fda47db8ee1d3eca8c42819cf1b65ab0ef7df7b8
URL: https://github.com/llvm/llvm-project/commit/fda47db8ee1d3eca8c42819cf1b65ab0ef7df7b8
DIFF: https://github.com/llvm/llvm-project/commit/fda47db8ee1d3eca8c42819cf1b65ab0ef7df7b8.diff
LOG: [Clang][Sema] Fix attribute mismatch warning for ObjC class properties
If a class declares an instance property, and an inheritor class declares a class property with the same name, Clang Sema currently treats the latter as an overridden property, and compares the attributes of the two properties to check for a mismatch. The resulting diagnostics might be misleading, since neither of the properties actually overrides the another one.
rdar://86018435
Differential Revision: https://reviews.llvm.org/D116412
Added:
clang/test/SemaObjC/class-property-inheritance.m
Modified:
clang/include/clang/AST/DeclObjC.h
clang/lib/AST/DeclObjC.cpp
clang/lib/Sema/SemaObjCProperty.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index f227561b8fcb..110b7dc0c6f2 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1071,6 +1071,9 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
+ ObjCPropertyDecl *getProperty(const IdentifierInfo *Id,
+ bool IsInstance) const;
+
ObjCPropertyDecl *
FindPropertyDeclaration(const IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index ba827a79c022..f15dd78929e2 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -232,6 +232,18 @@ ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
return &Ctx.Idents.get(ivarName.str());
}
+ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id,
+ bool IsInstance) const {
+ for (auto *LookupResult : lookup(Id)) {
+ if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) {
+ if (Prop->isInstanceProperty() == IsInstance) {
+ return Prop;
+ }
+ }
+ }
+ return nullptr;
+}
+
/// FindPropertyDeclaration - Finds declaration of the property given its name
/// in 'PropertyId' and returns it. It returns 0, if not found.
ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp
index 74c73ace3c5f..118afb81dd72 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -112,8 +112,8 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop,
return;
// Look for a property with the same name.
- if (ObjCPropertyDecl *ProtoProp =
- Proto->lookup(Prop->getDeclName()).find_first<ObjCPropertyDecl>()) {
+ if (ObjCPropertyDecl *ProtoProp = Proto->getProperty(
+ Prop->getIdentifier(), Prop->isInstanceProperty())) {
S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true);
return;
}
@@ -231,8 +231,8 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
bool FoundInSuper = false;
ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
- if (ObjCPropertyDecl *SuperProp =
- Super->lookup(Res->getDeclName()).find_first<ObjCPropertyDecl>()) {
+ if (ObjCPropertyDecl *SuperProp = Super->getProperty(
+ Res->getIdentifier(), Res->isInstanceProperty())) {
DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false);
FoundInSuper = true;
break;
diff --git a/clang/test/SemaObjC/class-property-inheritance.m b/clang/test/SemaObjC/class-property-inheritance.m
new file mode 100644
index 000000000000..9d8a4fe44053
--- /dev/null
+++ b/clang/test/SemaObjC/class-property-inheritance.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+ at class MyObject;
+
+
+ at interface TopClassWithClassProperty0
+ at property(nullable, readonly, strong, class) MyObject *foo;
+ at end
+
+ at interface SubClassWithClassProperty0 : TopClassWithClassProperty0
+ at property(nonnull, readonly, copy, class) MyObject *foo; // expected-warning {{'copy' attribute on property 'foo' does not match the property inherited from 'TopClassWithClassProperty0'}}
+ at end
+
+
+
+ at interface TopClassWithInstanceProperty1
+ at property(nullable, readonly, strong) MyObject *foo;
+ at end
+
+ at interface ClassWithClassProperty1 : TopClassWithInstanceProperty1
+ at property(nonnull, readonly, copy, class) MyObject *foo; // no-warning
+ at end
+
+ at interface SubClassWithInstanceProperty1 : ClassWithClassProperty1
+ at property(nullable, readonly, copy) MyObject *foo; // expected-warning {{'copy' attribute on property 'foo' does not match the property inherited from 'TopClassWithInstanceProperty1'}}
+ at end
+
+
+ at interface TopClassWithClassProperty2
+ at property(nullable, readonly, strong, class) MyObject *foo;
+ at end
+
+ at interface ClassWithInstanceProperty2 : TopClassWithClassProperty2
+ at property(nonnull, readonly, copy) MyObject *foo; // no-warning
+ at end
+
+ at interface SubClassWithClassProperty2 : ClassWithInstanceProperty2
+ at property(nonnull, readonly, copy, class) MyObject *foo; // expected-warning {{'copy' attribute on property 'foo' does not match the property inherited from 'TopClassWithClassProperty2'}}
+ at end
More information about the cfe-commits
mailing list