]> granicus.if.org Git - clang/commitdiff
[Sema][ObjC] Warn about mismatches in attributes between overriding and
authorAkira Hatanaka <ahatanaka@apple.com>
Wed, 20 Sep 2017 05:39:18 +0000 (05:39 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Wed, 20 Sep 2017 05:39:18 +0000 (05:39 +0000)
overridden methods when compiling for non-ARC.

Previously, clang would error out when compiling for ARC, but didn't
print any diagnostics when compiling for non-ARC.

This was pointed out in the patch review for attribute noescape:

https://reviews.llvm.org/D32210

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313717 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclObjC.cpp
test/Analysis/retain-release.m
test/SemaObjC/arc-nsconsumed-errors.m

index 4ebcf256ebf2686fe495a940668d8a104c75b9d0..33cae6c8013486b6dd1f8c67e34177ed63b73aa8 100644 (file)
@@ -507,6 +507,9 @@ def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas,
                                     PragmaClangAttribute, PragmaPack]>;
 def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
 def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
+def NSConsumedMismatch : DiagGroup<"nsconsumed-mismatch">;
+def NSReturnsMismatch : DiagGroup<"nsreturns-mismatch">;
+
 def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
 def UnknownAttributes : DiagGroup<"unknown-attributes">;
 def IgnoredAttributes : DiagGroup<"ignored-attributes">;
index f851e29431df2fd4c32526b56dbf1b8029654c69..3974fe0eea51d54f2ae27dd1e702f4f38504e62b 100644 (file)
@@ -8244,12 +8244,12 @@ def err_c99_array_usage_cxx : Error<
   "feature, not permitted in C++">;
 def err_type_unsupported : Error<
   "%0 is not supported on this target">;
-def err_nsconsumed_attribute_mismatch : Error<
+def warn_nsconsumed_attribute_mismatch : Warning<
   "overriding method has mismatched ns_consumed attribute on its"
-  " parameter">;
-def err_nsreturns_retained_attribute_mismatch : Error<
+  " parameter">, InGroup<NSConsumedMismatch>;
+def warn_nsreturns_retained_attribute_mismatch : Warning<
   "overriding method has mismatched ns_returns_%select{not_retained|retained}0"
-  " attributes">;
+  " attributes">, InGroup<NSReturnsMismatch>;
   
 def note_getter_unavailable : Note<
   "or because setter is declared here, but no getter method %0 is found">;
index 967573011d0dce80940d3a857d97e761c6273be6..5f9f608b75cc7b050437469156c4dd126a7e52d3 100644 (file)
@@ -157,34 +157,36 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
            diag::note_related_result_type_overridden);
   }
   if (getLangOpts().ObjCAutoRefCount) {
-    if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
-         Overridden->hasAttr<NSReturnsRetainedAttr>())) {
-        Diag(NewMethod->getLocation(),
-             diag::err_nsreturns_retained_attribute_mismatch) << 1;
-        Diag(Overridden->getLocation(), diag::note_previous_decl) 
-        << "method";
-    }
-    if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
-              Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
-        Diag(NewMethod->getLocation(),
-             diag::err_nsreturns_retained_attribute_mismatch) << 0;
-        Diag(Overridden->getLocation(), diag::note_previous_decl) 
-        << "method";
-    }
-    ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
-                                         oe = Overridden->param_end();
-    for (ObjCMethodDecl::param_iterator
-           ni = NewMethod->param_begin(), ne = NewMethod->param_end();
-         ni != ne && oi != oe; ++ni, ++oi) {
-      const ParmVarDecl *oldDecl = (*oi);
-      ParmVarDecl *newDecl = (*ni);
-      if (newDecl->hasAttr<NSConsumedAttr>() != 
-          oldDecl->hasAttr<NSConsumedAttr>()) {
-        Diag(newDecl->getLocation(),
-             diag::err_nsconsumed_attribute_mismatch);
-        Diag(oldDecl->getLocation(), diag::note_previous_decl) 
-          << "parameter";
-      }
+    Diags.setSeverity(diag::warn_nsreturns_retained_attribute_mismatch,
+                      diag::Severity::Error, SourceLocation());
+    Diags.setSeverity(diag::warn_nsconsumed_attribute_mismatch,
+                      diag::Severity::Error, SourceLocation());
+  }
+
+  if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
+       Overridden->hasAttr<NSReturnsRetainedAttr>())) {
+    Diag(NewMethod->getLocation(),
+         diag::warn_nsreturns_retained_attribute_mismatch) << 1;
+    Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";
+  }
+  if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
+       Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
+    Diag(NewMethod->getLocation(),
+         diag::warn_nsreturns_retained_attribute_mismatch) << 0;
+    Diag(Overridden->getLocation(), diag::note_previous_decl)  << "method";
+  }
+
+  ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
+                                       oe = Overridden->param_end();
+  for (ObjCMethodDecl::param_iterator ni = NewMethod->param_begin(),
+                                      ne = NewMethod->param_end();
+       ni != ne && oi != oe; ++ni, ++oi) {
+    const ParmVarDecl *oldDecl = (*oi);
+    ParmVarDecl *newDecl = (*ni);
+    if (newDecl->hasAttr<NSConsumedAttr>() !=
+        oldDecl->hasAttr<NSConsumedAttr>()) {
+      Diag(newDecl->getLocation(), diag::warn_nsconsumed_attribute_mismatch);
+      Diag(oldDecl->getLocation(), diag::note_previous_decl) << "parameter";
     }
   }
 }
index 8e4dcb59780bdddc31f9ea98d050f164c6820630..a1cc62cb3593f85a22863d6accd5ab8685d9a1d0 100644 (file)
@@ -1787,15 +1787,15 @@ CFArrayRef camel_copymachine() {
 
 // rdar://problem/8024350
 @protocol F18P
-- (id) clone;
+- (id) clone; // expected-note 2 {{method declared here}}
 @end
 @interface F18 : NSObject<F18P> @end
 @interface F18(Cat)
-- (id) clone NS_RETURNS_RETAINED;
+- (id) clone NS_RETURNS_RETAINED; // expected-warning {{overriding method has mismatched ns_returns_retained attributes}}
 @end
 
 @implementation F18
-- (id) clone {
+- (id) clone { // expected-warning {{overriding method has mismatched ns_returns_retained attributes}}
   return [F18 alloc];
 }
 @end
index 62e74aabaffd1a6e0019f90aae8dab7bbc8afc09..fd0d388ca9c6529b67a0a92d7d9fb34d8a525625 100644 (file)
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 -DOBJCARC %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
 // rdar://10187884
 
+#ifdef OBJCARC
 typedef void (^blk)(id arg1, __attribute((ns_consumed)) id arg2);
 typedef void (^blk1)(__attribute((ns_consumed))id arg1, __attribute((ns_consumed)) id arg2);
 blk a = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
@@ -18,3 +20,12 @@ blk1 b2 = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; // expected-err
 blk1 c3 = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){};
 
 blk1 d4 = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}
+#else
+@interface Sub
+-(void) m:(id)p; // expected-note {{parameter declared here}}
+@end
+
+@interface Super : Sub
+-(void) m:(__attribute__((ns_consumed)) id)p; // expected-warning {{overriding method has mismatched ns_consumed attribute on its parameter}}
+@end
+#endif