r268781 - ObjC kindof: set the type of a conditional expression when involving kindof.

Manman Ren via cfe-commits cfe-commits at lists.llvm.org
Fri May 6 12:35:02 PDT 2016


Author: mren
Date: Fri May  6 14:35:02 2016
New Revision: 268781

URL: http://llvm.org/viewvc/llvm-project?rev=268781&view=rev
Log:
ObjC kindof: set the type of a conditional expression when involving kindof.

When either LHS or RHS is a kindof type, we return a kindof type.

rdar://problem/20513780

Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/test/SemaObjC/kindof.m

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=268781&r1=268780&r2=268781&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri May  6 14:35:02 2016
@@ -7163,6 +7163,11 @@ QualType ASTContext::areCommonBaseCompat
   if (!LDecl || !RDecl)
     return QualType();
 
+  // When either LHS or RHS is a kindof type, we should return a kindof type.
+  // For example, for common base of kindof(ASub1) and kindof(ASub2), we return
+  // kindof(A).
+  bool anyKindOf = LHS->isKindOfType() || RHS->isKindOfType();
+
   // Follow the left-hand side up the class hierarchy until we either hit a
   // root or find the RHS. Record the ancestors in case we don't find it.
   llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4>
@@ -7197,10 +7202,12 @@ QualType ASTContext::areCommonBaseCompat
         anyChanges = true;
 
       // If anything in the LHS will have changed, build a new result type.
-      if (anyChanges) {
+      // If we need to return a kindof type but LHS is not a kindof type, we
+      // build a new result type.
+      if (anyChanges || LHS->isKindOfType() != anyKindOf) {
         QualType Result = getObjCInterfaceType(LHS->getInterface());
         Result = getObjCObjectType(Result, LHSTypeArgs, Protocols,
-                                   LHS->isKindOfType());
+                                   anyKindOf || LHS->isKindOfType());
         return getObjCObjectPointerType(Result);
       }
 
@@ -7245,10 +7252,12 @@ QualType ASTContext::areCommonBaseCompat
       if (!Protocols.empty())
         anyChanges = true;
 
-      if (anyChanges) {
+      // If we need to return a kindof type but RHS is not a kindof type, we
+      // build a new result type.
+      if (anyChanges || RHS->isKindOfType() != anyKindOf) {
         QualType Result = getObjCInterfaceType(RHS->getInterface());
         Result = getObjCObjectType(Result, RHSTypeArgs, Protocols,
-                                   RHS->isKindOfType());
+                                   anyKindOf || RHS->isKindOfType());
         return getObjCObjectPointerType(Result);
       }
 

Modified: cfe/trunk/test/SemaObjC/kindof.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/kindof.m?rev=268781&r1=268780&r2=268781&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/kindof.m (original)
+++ cfe/trunk/test/SemaObjC/kindof.m Fri May  6 14:35:02 2016
@@ -187,6 +187,39 @@ void test_crosscast_conversions(void) {
   NSString_obj = kindof_NSNumber_obj; // expected-warning{{from '__kindof NSNumber *'}}
 }
 
+ at interface NSCell : NSObject
+ at end
+ at interface NSCellSub : NSCell
+ at end
+ at interface NSCellSub2 : NSCell
+ at end
+ at interface NSCellSubSub : NSCellSub
+ at end
+
+typedef signed char BOOL;
+void test_conditional(BOOL flag) {
+  NSCellSubSub *result;
+  __kindof NSCellSub *kindof_Sub;
+  NSCell *cell;
+  NSCellSub *sub;
+  NSCellSub2 *sub2;
+  NSCellSubSub *subsub;
+
+  // LHS is kindof NSCellSub, RHS is NSCell --> kindof NSCell
+  // LHS is kindof NSCellSub, RHS is NSCellSub --> kindof NSCellSub
+  // LHS is kindof NSCellSub, RHS is NSCellSub2 --> kindof NSCell
+  // LHS is kindof NSCellSub, RHS is NSCellSubSub --> kindof NSCellSub
+  result = flag ? kindof_Sub : cell;
+  result = flag ? kindof_Sub : sub;
+  result = flag ? kindof_Sub : sub2;
+  result = flag ? kindof_Sub : subsub;
+
+  result = flag ? cell : kindof_Sub;
+  result = flag ? sub : kindof_Sub;
+  result = flag ? sub2 : kindof_Sub;
+  result = flag ? subsub : kindof_Sub;
+}
+
 // ---------------------------------------------------------------------------
 // Blocks
 // ---------------------------------------------------------------------------
@@ -277,7 +310,6 @@ void test(__kindof Bar *kBar) {
 }
 
 // Make sure we don't emit warning about no method found.
-typedef signed char BOOL;
 @interface A : NSObject
 @property (readonly, getter=isActive) BOOL active;
 @end




More information about the cfe-commits mailing list