[cfe-commits] r133123 - in /cfe/trunk: lib/Sema/SemaDeclObjC.cpp test/SemaObjC/method-lookup-3.m

John McCall rjmccall at apple.com
Wed Jun 15 18:15:19 PDT 2011


Author: rjmccall
Date: Wed Jun 15 20:15:19 2011
New Revision: 133123

URL: http://llvm.org/viewvc/llvm-project?rev=133123&view=rev
Log:
Weaken the type-matching rules for methods that return aggregates when
complaining about mismatches in the global method pool.


Modified:
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/SemaObjC/method-lookup-3.m

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=133123&r1=133122&r2=133123&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Jun 15 20:15:19 2011
@@ -1652,6 +1652,10 @@
   return CDecl;
 }
 
+static bool tryMatchRecordTypes(ASTContext &Context,
+                                Sema::MethodMatchStrategy strategy,
+                                const Type *left, const Type *right);
+
 static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
                        QualType leftQT, QualType rightQT) {
   const Type *left =
@@ -1681,10 +1685,11 @@
   if (isa<VectorType>(right)) return false;
 
   // - references should only match references of identical type
-  // - structs, unions, and Objective-C objects must match exactly
+  // - structs, unions, and Objective-C objects must match more-or-less
+  //   exactly
   // - everything else should be a scalar
   if (!left->isScalarType() || !right->isScalarType())
-    return false;
+    return tryMatchRecordTypes(Context, strategy, left, right);
 
   // Make scalars agree in kind, except count bools as chars.
   Type::ScalarTypeKind leftSK = left->getScalarTypeKind();
@@ -1698,6 +1703,36 @@
   return (leftSK == rightSK);
 }
 
+static bool tryMatchRecordTypes(ASTContext &Context,
+                                Sema::MethodMatchStrategy strategy,
+                                const Type *lt, const Type *rt) {
+  assert(lt && rt && lt != rt);
+
+  if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
+  RecordDecl *left = cast<RecordType>(lt)->getDecl();
+  RecordDecl *right = cast<RecordType>(rt)->getDecl();
+
+  // Require union-hood to match.
+  if (left->isUnion() != right->isUnion()) return false;
+
+  // Require an exact match if either is non-POD.
+  if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) ||
+      (isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD()))
+    return false;
+
+  // Require size and alignment to match.
+  if (Context.getTypeInfo(lt) != Context.getTypeInfo(rt)) return false;
+
+  // Require fields to match.
+  RecordDecl::field_iterator li = left->field_begin(), le = left->field_end();
+  RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end();
+  for (; li != le && ri != re; ++li, ++ri) {
+    if (!matchTypes(Context, strategy, li->getType(), ri->getType()))
+      return false;
+  }
+  return (li == le && ri == re);
+}
+
 /// MatchTwoMethodDeclarations - Checks that two methods have matching type and
 /// returns true, or false, accordingly.
 /// TODO: Handle protocol list; such as id<p1,p2> in type comparisons

Modified: cfe/trunk/test/SemaObjC/method-lookup-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/method-lookup-3.m?rev=133123&r1=133122&r2=133123&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/method-lookup-3.m (original)
+++ cfe/trunk/test/SemaObjC/method-lookup-3.m Wed Jun 15 20:15:19 2011
@@ -55,3 +55,19 @@
 void f6(id<A> a0) {
   Abstract *l = [a0 x];
 }
+
+struct test3a { int x, y; };
+struct test3b { unsigned x, y; };
+ at interface Test3A - (struct test3a) test3; @end
+ at interface Test3B - (struct test3b) test3; @end
+void test3(id x) {
+  (void) [x test3];
+}
+
+struct test4a { int x, y; };
+struct test4b { float x, y; };
+ at interface Test4A - (struct test4a) test4; @end //expected-note{{using}}
+ at interface Test4B - (struct test4b) test4; @end //expected-note{{also found}}
+void test4(id x) {
+  (void) [x test4]; //expected-warning {{multiple methods named 'test4' found}}
+}





More information about the cfe-commits mailing list