[cfe-commits] r134655 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp test/SemaObjCXX/arc-unavailable-for-weakref.mm

Fariborz Jahanian fjahanian at apple.com
Thu Jul 7 16:04:17 PDT 2011


Author: fjahanian
Date: Thu Jul  7 18:04:17 2011
New Revision: 134655

URL: http://llvm.org/viewvc/llvm-project?rev=134655&view=rev
Log:
objc++-arc: diagnose assignment/cast of a weak-unavailable
object to a __weak object/type. // rdar://9732636.
One item is yet todo.

Added:
    cfe/trunk/test/SemaObjCXX/arc-unavailable-for-weakref.mm
Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=134655&r1=134654&r2=134655&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jul  7 18:04:17 2011
@@ -5626,6 +5626,9 @@
   /// retainable pointers and other pointer kinds.
   void CheckObjCARCConversion(SourceRange castRange, QualType castType, 
                               Expr *&op, CheckedConversionKind CCK);
+    
+  bool CheckObjCARCUnavailableWeakConversion(QualType castType,
+                                             QualType ExprType);
 
   /// checkRetainCycles - Check whether an Objective-C message send
   /// might create an obvious retain cycle.

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=134655&r1=134654&r2=134655&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Thu Jul  7 18:04:17 2011
@@ -1717,7 +1717,8 @@
     Kind = CK_Dependent;
     return Owned(CastExpr);
   }
-
+  
+  QualType origCastExprType = CastExpr->getType();
   if (VK == VK_RValue && !CastTy->isRecordType()) {
     ExprResult CastExprRes = DefaultFunctionArrayLvalueConversion(CastExpr);
     if (CastExprRes.isInvalid())
@@ -1773,8 +1774,15 @@
     }
   }
 
-  if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
+  if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success) {
     CheckObjCARCConversion(R, CastTy, CastExpr, CCK);
+    if (!CheckObjCARCUnavailableWeakConversion(CastTy, 
+                                               origCastExprType))
+      Diag(CastExpr->getLocStart(), 
+           diag::err_arc_cast_of_weak_unavailable)
+      << origCastExprType << CastTy 
+      << CastExpr->getSourceRange();
+  }
 
   if (tcr != TC_Success && msg != 0) {
     if (CastExpr->getType() == Context.OverloadTy) {

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=134655&r1=134654&r2=134655&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jul  7 18:04:17 2011
@@ -4066,22 +4066,12 @@
         }
       }
     } 
-    else {
-      QualType canCastType = 
-        Context.getCanonicalType(castType).getUnqualifiedType();
-        if (isa<ObjCObjectPointerType>(canCastType) &&
-            castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
-            castExprType->isObjCObjectPointerType()) {
-          if (const ObjCObjectPointerType *ObjT =
-              castExprType->getAs<ObjCObjectPointerType>())
-            if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) {
-              Diag(castExpr->getLocStart(), 
-                   diag::err_arc_cast_of_weak_unavailable)
+    else if (!CheckObjCARCUnavailableWeakConversion(castType, castExprType)) {
+           Diag(castExpr->getLocStart(), 
+                diag::err_arc_cast_of_weak_unavailable)
                 << castExprType << castType 
                 << castExpr->getSourceRange();
-              return ExprError();
-            }
-        }
+          return ExprError();
     }
   }
   
@@ -5300,12 +5290,8 @@
         checkObjCPointerTypesForAssignment(*this, lhsType, rhsType);
       if (getLangOptions().ObjCAutoRefCount &&
           result == Compatible && 
-          origLhsType.getObjCLifetime() == Qualifiers::OCL_Weak) {
-        if (const ObjCObjectPointerType *ObjT = 
-              rhsType->getAs<ObjCObjectPointerType>())
-          if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable())
-            result = IncompatibleObjCWeakRef;
-      }
+          !CheckObjCARCUnavailableWeakConversion(origLhsType, rhsType))
+        result = IncompatibleObjCWeakRef;
       return result;
     }
 
@@ -5474,8 +5460,12 @@
                                                  AA_Assigning);
       if (Res.isInvalid())
         return Incompatible;
+      Sema::AssignConvertType result = Compatible;
+      if (getLangOptions().ObjCAutoRefCount &&
+          !CheckObjCARCUnavailableWeakConversion(lhsType, rExpr.get()->getType()))
+        result = IncompatibleObjCWeakRef;
       rExpr = move(Res);
-      return Compatible;
+      return result;
     }
 
     // FIXME: Currently, we fall through and treat C++ classes like C

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=134655&r1=134654&r2=134655&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Thu Jul  7 18:04:17 2011
@@ -1771,6 +1771,23 @@
     << castRange << castExpr->getSourceRange();
 }
 
+bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType,
+                                                 QualType exprType) {
+  QualType canCastType = 
+    Context.getCanonicalType(castType).getUnqualifiedType();
+  QualType canExprType = 
+    Context.getCanonicalType(exprType).getUnqualifiedType();
+  if (isa<ObjCObjectPointerType>(canCastType) &&
+      castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
+      canExprType->isObjCObjectPointerType()) {
+    if (const ObjCObjectPointerType *ObjT =
+        canExprType->getAs<ObjCObjectPointerType>())
+      if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable())
+        return false;
+  }
+  return true;
+}
+
 /// Look for an ObjCReclaimReturnedObject cast and destroy it.
 static Expr *maybeUndoReclaimObject(Expr *e) {
   // For now, we just undo operands that are *immediately* reclaim

Added: cfe/trunk/test/SemaObjCXX/arc-unavailable-for-weakref.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-unavailable-for-weakref.mm?rev=134655&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-unavailable-for-weakref.mm (added)
+++ cfe/trunk/test/SemaObjCXX/arc-unavailable-for-weakref.mm Thu Jul  7 18:04:17 2011
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s
+// rdar://9693477
+
+__attribute__((objc_arc_weak_reference_unavailable))
+ at interface NSOptOut1072  // expected-note {{class is declared here}}
+ at end
+
+ at interface sub : NSOptOut1072 @end // expected-note 2 {{class is declared here}}
+
+int main() {
+  __weak sub *w2; // expected-error {{class is incompatible with __weak references}}
+
+  __weak NSOptOut1072 *ns1; // expected-error {{class is incompatible with __weak references}}
+
+  id obj;
+
+  ns1 = (__weak sub *)obj; // expected-error {{assignment of a weak-unavailable object to a __weak object}} \
+                           // expected-error {{class is incompatible with __weak references}}
+}
+
+// rdar://9732636
+__attribute__((objc_arc_weak_reference_unavailable))
+ at interface NOWEAK
++ (id) new;
+ at end
+
+NOWEAK * Test9732636() {
+  NOWEAK * strong1 = [NOWEAK new];
+  __weak id weak1;
+  weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+// FIXME. NYI.
+  __weak id weak2 = strong1; // expected-FIXME {{assignment of a weak-unavailable object to a __weak object}}
+  return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *__strong' to a __weak object of type '__weak id'}}
+}
+





More information about the cfe-commits mailing list