]> granicus.if.org Git - clang/commitdiff
objective-C: Do not warn if align attribute on method
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 24 Aug 2012 23:50:13 +0000 (23:50 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 24 Aug 2012 23:50:13 +0000 (23:50 +0000)
declaration is not provided. It is only necessary on
the method implementation. // rdar://11593375

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

lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/method-attributes.m

index 9da4d69382efc87e7e35e5bf88290f3b0db8372a..457cb1b9757df340d5421bfd4485cf27c89af32d 100644 (file)
@@ -2434,6 +2434,15 @@ CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
   return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
 }
 
+static inline
+unsigned countAlignAttr(const AttrVec &A) {
+  unsigned count=0;
+  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+    if ((*i)->getKind() == attr::Aligned)
+      ++count;
+  return count;
+}
+
 static inline
 bool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD,
                                         const AttrVec &A) {
@@ -2441,20 +2450,34 @@ bool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD,
   // No need to issue any diagnostics on method definition with attributes.
   if (!IMD)
     return false;
-
+  
   // method declared in interface has no attribute. 
-  // But implementation has attributes. This is invalid
+  // But implementation has attributes. This is invalid.
+  // Except when implementation has 'Align' attribute which is
+  // immaterial to method declared in interface.
   if (!IMD->hasAttrs())
-    return true;
+    return (A.size() > countAlignAttr(A));
 
   const AttrVec &D = IMD->getAttrs();
-  if (D.size() != A.size())
-    return true;
 
+  unsigned countAlignOnImpl = countAlignAttr(A);
+  if (!countAlignOnImpl && (A.size() != D.size()))
+    return true;
+  else if (countAlignOnImpl) {
+    unsigned countAlignOnDecl = countAlignAttr(D);
+    if (countAlignOnDecl && (A.size() != D.size()))
+      return true;
+    else if (!countAlignOnDecl && 
+             ((A.size()-countAlignOnImpl) != D.size()))
+      return true;
+  }
+  
   // attributes on method declaration and definition must match exactly.
   // Note that we have at most a couple of attributes on methods, so this
   // n*n search is good enough.
   for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i) {
+    if ((*i)->getKind() == attr::Aligned)
+      continue;
     bool match = false;
     for (AttrVec::const_iterator i1 = D.begin(), e1 = D.end(); i1 != e1; ++i1) {
       if ((*i)->getKind() == (*i1)->getKind()) {
@@ -2465,6 +2488,7 @@ bool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD,
     if (!match)
       return true;
   }
+  
   return false;
 }
 
index f7252af1f1b75afe83787bcdb41a8f274f0cd833..b402d52a42a10bb9e7877da34c619877c08e9a55 100644 (file)
 - (IBAction)doSomething2:(id)sender {} // expected-warning {{attributes on method implementation and its declaration must match}}
 - (IBAction)doSomething3:(id)sender {}
 @end
+
+// rdar://11593375
+@interface NSObject @end
+
+@interface Test : NSObject
+-(id)method __attribute__((deprecated));
+-(id)method1;
+-(id)method2 __attribute__((aligned(16)));
+- (id) method3: (int)arg1 __attribute__((aligned(16)))  __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{method 'method3:' declared here}}
+- (id) method4: (int)arg1 __attribute__((aligned(16)))  __attribute__((deprecated)) __attribute__((unavailable)); 
+@end
+
+@implementation Test
+-(id)method __attribute__((aligned(16))) __attribute__((aligned(16))) __attribute__((deprecated)) {
+    return self;
+}
+-(id)method1 __attribute__((aligned(16))) {
+    return self;
+}
+-(id)method2 {
+    return self;
+}
+- (id) method3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) {  // expected-warning {{attributes on method implementation and its declaration must match}}
+        return self;
+}
+- (id) method4: (int)arg1 __attribute__((aligned(16))) __attribute__((deprecated)) __attribute__((unavailable)) {
+  return self;
+}
+@end