[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