[cfe-commits] r134275 - in /cfe/trunk: include/clang/Parse/Parser.h include/clang/Sema/Sema.h lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExpr.cpp test/ARCMT/checking.m test/SemaObjC/arc-type-conversion.m test/SemaObjCXX/arc-type-conversion.mm

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Jul 1 15:22:59 PDT 2011


Author: akirtzidis
Date: Fri Jul  1 17:22:59 2011
New Revision: 134275

URL: http://llvm.org/viewvc/llvm-project?rev=134275&view=rev
Log:
[ARC] When casting from a pointer to an objective-c object with known ownership, if the
cast type has no ownership specified, implicitly "transfer" the ownership of the cast'ed type
to the cast type:

id x;
(NSString**)&x; // Casting as (__strong NSString**).

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/ARCMT/checking.m
    cfe/trunk/test/SemaObjC/arc-type-conversion.m
    cfe/trunk/test/SemaObjCXX/arc-type-conversion.mm

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Jul  1 17:22:59 2011
@@ -1135,10 +1135,10 @@
   ExprResult ParseCastExpression(bool isUnaryExpression,
                                  bool isAddressOfOperand,
                                  bool &NotCastExpr,
-                                 ParsedType TypeOfCast);
+                                 bool isTypeCast);
   ExprResult ParseCastExpression(bool isUnaryExpression,
                                  bool isAddressOfOperand = false,
-                                 ParsedType TypeOfCast = ParsedType());
+                                 bool isTypeCast = false);
 
   /// Returns true if the next token would start a postfix-expression
   /// suffix.
@@ -1179,7 +1179,7 @@
   };
   ExprResult ParseParenExpression(ParenParseOption &ExprType,
                                         bool stopIfCastExpr,
-                                        ParsedType TypeOfCast,
+                                        bool isTypeCast,
                                         ParsedType &CastTy,
                                         SourceLocation &RParenLoc);
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jul  1 17:22:59 2011
@@ -2376,8 +2376,8 @@
                                 MultiExprArg ExecConfig, SourceLocation GGGLoc);
 
   ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
-                           ParsedType Ty, SourceLocation RParenLoc,
-                           Expr *Op);
+                           Declarator &D, ParsedType &Ty,
+                           SourceLocation RParenLoc, Expr *Op);
   ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
                                  TypeSourceInfo *Ty,
                                  SourceLocation RParenLoc,

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri Jul  1 17:22:59 2011
@@ -220,7 +220,7 @@
   if (Tok.is(tok::kw_throw))
     return ParseThrowExpression();
 
-  ExprResult LHS = ParseCastExpression(false, false, ParsedType());
+  ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false);
   return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
 }
 
@@ -415,12 +415,12 @@
 ///
 ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
                                        bool isAddressOfOperand,
-                                       ParsedType TypeOfCast) {
+                                       bool isTypeCast) {
   bool NotCastExpr;
   ExprResult Res = ParseCastExpression(isUnaryExpression,
                                        isAddressOfOperand,
                                        NotCastExpr,
-                                       TypeOfCast);
+                                       isTypeCast);
   if (NotCastExpr)
     Diag(Tok, diag::err_expected_expression);
   return move(Res);
@@ -589,7 +589,7 @@
 ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
                                        bool isAddressOfOperand,
                                        bool &NotCastExpr,
-                                       ParsedType TypeOfCast) {
+                                       bool isTypeCast) {
   ExprResult Res;
   tok::TokenKind SavedKind = Tok.getKind();
   NotCastExpr = false;
@@ -620,7 +620,7 @@
       ColonProtectionRAIIObject X(*this, false);
 
       Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
-                                 TypeOfCast, CastTy, RParenLoc);
+                                 isTypeCast, CastTy, RParenLoc);
     }
 
     switch (ParenExprType) {
@@ -952,7 +952,7 @@
       return ExprError();
     if (!Tok.is(tok::annot_cxxscope))
       return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
-                                 NotCastExpr, TypeOfCast);
+                                 NotCastExpr, isTypeCast);
 
     Token Next = NextToken();
     if (Next.is(tok::annot_template_id)) {
@@ -965,7 +965,7 @@
         ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
         AnnotateTemplateIdTokenAsType();
         return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
-                                   NotCastExpr, TypeOfCast);
+                                   NotCastExpr, isTypeCast);
       }
     }
 
@@ -982,7 +982,7 @@
       // expression.
       AnnotateTemplateIdTokenAsType();
       return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
-                                 NotCastExpr, TypeOfCast);
+                                 NotCastExpr, isTypeCast);
     }
 
     // Fall through to treat the template-id as an id-expression.
@@ -1105,7 +1105,7 @@
     Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
     ConsumeCodeCompletionToken();
     return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 
-                               NotCastExpr, TypeOfCast);
+                               NotCastExpr, isTypeCast);
   case tok::l_square:
     // These can be followed by postfix-expr pieces.
     if (getLang().ObjC1)
@@ -1422,7 +1422,7 @@
     EnterExpressionEvaluationContext Unevaluated(Actions,
                                                  Sema::Unevaluated);
     Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 
-                                   ParsedType(), CastTy, RParenLoc);
+                                   false, CastTy, RParenLoc);
     CastRange = SourceRange(LParenLoc, RParenLoc);
 
     // If ParseParenExpression parsed a '(typename)' sequence only, then this is
@@ -1746,7 +1746,7 @@
 ///         (__bridge_retained type-name) cast-expression
 ExprResult
 Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
-                             ParsedType TypeOfCast, ParsedType &CastTy,
+                             bool isTypeCast, ParsedType &CastTy,
                              SourceLocation &RParenLoc) {
   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
   GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
@@ -1804,7 +1804,7 @@
              
     TypeResult Ty = ParseTypeName();
     SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, OpenLoc);
-    ExprResult SubExpr = ParseCastExpression(false, false, ParsedType());
+    ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
     
     if (Ty.isInvalid() || SubExpr.isInvalid())
       return ExprError();
@@ -1826,20 +1826,23 @@
       return ParseCXXAmbiguousParenExpression(ExprType, CastTy,
                                               OpenLoc, RParenLoc);
 
-    TypeResult Ty;
-    
-    {
-      InMessageExpressionRAIIObject InMessage(*this, false);
-      Ty = ParseTypeName();
-    }
+    // Parse the type declarator.
+    DeclSpec DS(AttrFactory);
+    ParseSpecifierQualifierList(DS);
+    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+    ParseDeclarator(DeclaratorInfo);
     
     // If our type is followed by an identifier and either ':' or ']', then 
     // this is probably an Objective-C message send where the leading '[' is
     // missing. Recover as if that were the case.
-    if (!Ty.isInvalid() && Tok.is(tok::identifier) && !InMessageExpression &&
-        getLang().ObjC1 && !Ty.get().get().isNull() &&
-        (NextToken().is(tok::colon) || NextToken().is(tok::r_square)) &&
-        Ty.get().get()->isObjCObjectOrInterfaceType()) {
+    if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
+        !InMessageExpression && getLang().ObjC1 &&
+        (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
+      TypeResult Ty;
+      {
+        InMessageExpressionRAIIObject InMessage(*this, false);
+        Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+      }
       Result = ParseObjCMessageExpressionBody(SourceLocation(), 
                                               SourceLocation(), 
                                               Ty.get(), 0);
@@ -1852,21 +1855,31 @@
 
       if (Tok.is(tok::l_brace)) {
         ExprType = CompoundLiteral;
+        TypeResult Ty;
+        {
+          InMessageExpressionRAIIObject InMessage(*this, false);
+          Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+        }
         return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
       }
 
       if (ExprType == CastExpr) {
         // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
 
-        if (Ty.isInvalid())
+        if (DeclaratorInfo.isInvalidType())
           return ExprError();
 
-        CastTy = Ty.get();
-
         // Note that this doesn't parse the subsequent cast-expression, it just
         // returns the parsed type to the callee.
-        if (stopIfCastExpr)
+        if (stopIfCastExpr) {
+          TypeResult Ty;
+          {
+            InMessageExpressionRAIIObject InMessage(*this, false);
+            Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+          }
+          CastTy = Ty.get();
           return ExprResult();
+        }
         
         // Reject the cast of super idiom in ObjC.
         if (Tok.is(tok::identifier) && getLang().ObjC1 &&
@@ -1880,17 +1893,21 @@
 
         // Parse the cast-expression that follows it next.
         // TODO: For cast expression with CastTy.
-        Result = ParseCastExpression(false, false, CastTy);
-        if (!Result.isInvalid())
-          Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, CastTy, 
+        Result = ParseCastExpression(/*isUnaryExpression=*/false,
+                                     /*isAddressOfOperand=*/false,
+                                     /*isTypeCast=*/true);
+        if (!Result.isInvalid()) {
+          Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
+                                         DeclaratorInfo, CastTy, 
                                          RParenLoc, Result.take());
+        }
         return move(Result);
       }
 
       Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
       return ExprError();
     }
-  } else if (TypeOfCast) {
+  } else if (isTypeCast) {
     // Parse the expression-list.
     InMessageExpressionRAIIObject InMessage(*this, false);
     

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri Jul  1 17:22:59 2011
@@ -2200,7 +2200,8 @@
       Result = ParseCastExpression(false/*isUnaryExpression*/,
                                    false/*isAddressofOperand*/,
                                    NotCastExpr,
-                                   ParsedType()/*TypeOfCast*/);
+                                   // type-id has priority.
+                                   true/*isTypeCast*/);
     }
 
     // If we parsed a cast-expression, it's really a type-id, otherwise it's
@@ -2219,7 +2220,11 @@
   ConsumeAnyToken();
 
   if (ParseAs >= CompoundLiteral) {
-    TypeResult Ty = ParseTypeName();
+    // Parse the type declarator.
+    DeclSpec DS(AttrFactory);
+    ParseSpecifierQualifierList(DS);
+    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+    ParseDeclarator(DeclaratorInfo);
 
     // Match the ')'.
     if (Tok.is(tok::r_paren))
@@ -2229,21 +2234,21 @@
 
     if (ParseAs == CompoundLiteral) {
       ExprType = CompoundLiteral;
+      TypeResult Ty = ParseTypeName();
       return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
     }
 
     // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
     assert(ParseAs == CastExpr);
 
-    if (Ty.isInvalid())
+    if (DeclaratorInfo.isInvalidType())
       return ExprError();
 
-    CastTy = Ty.get();
-
     // Result is what ParseCastExpression returned earlier.
     if (!Result.isInvalid())
-      Result = Actions.ActOnCastExpr(getCurScope(), LParenLoc, CastTy, RParenLoc,
-                                     Result.take());
+      Result = Actions.ActOnCastExpr(getCurScope(), LParenLoc,
+                                     DeclaratorInfo, CastTy,
+                                     RParenLoc, Result.take());
     return move(Result);
   }
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul  1 17:22:59 2011
@@ -4138,15 +4138,23 @@
 }
 
 ExprResult
-Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty,
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                    Declarator &D, ParsedType &Ty,
                     SourceLocation RParenLoc, Expr *castExpr) {
-  assert((Ty != 0) && (castExpr != 0) &&
+  assert(!D.isInvalidType() && (castExpr != 0) &&
          "ActOnCastExpr(): missing type or expr");
 
-  TypeSourceInfo *castTInfo;
-  QualType castType = GetTypeFromParser(Ty, &castTInfo);
-  if (!castTInfo)
-    castTInfo = Context.getTrivialTypeSourceInfo(castType);
+  TypeSourceInfo *castTInfo = GetTypeForDeclaratorCast(D, castExpr->getType());
+  if (D.isInvalidType())
+    return ExprError();
+
+  if (getLangOptions().CPlusPlus) {
+    // Check that there are no default arguments (C++ only).
+    CheckExtraCXXDefaultArguments(D);
+  }
+
+  QualType castType = castTInfo->getType();
+  Ty = CreateParsedType(castType, castTInfo);
 
   bool isVectorLiteral = false;
 

Modified: cfe/trunk/test/ARCMT/checking.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/checking.m?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/checking.m (original)
+++ cfe/trunk/test/ARCMT/checking.m Fri Jul  1 17:22:59 2011
@@ -100,7 +100,7 @@
   (void)(int*)arg; // expected-error {{disallowed}}
   (void)(id)arg;
   (void)(__autoreleasing id*)arg; // expected-error {{disallowed}}
-  (void)(id*)arg; // expected-error {{pointer to non-const type 'id' with no explicit ownership}} expected-error {{disallowed}}
+  (void)(id*)arg; // expected-error {{disallowed}}
 
   (void)(__autoreleasing id**)voidp_val;
   (void)(void*)voidp_val;

Modified: cfe/trunk/test/SemaObjC/arc-type-conversion.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-type-conversion.m?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-type-conversion.m (original)
+++ cfe/trunk/test/SemaObjC/arc-type-conversion.m Fri Jul  1 17:22:59 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-nonfragile-abi -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-nonfragile-abi -verify -fblocks %s
 
 void * cvt(id arg)
 {
@@ -6,7 +6,7 @@
   (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}}
   (void)(id)arg;
   (void)(__autoreleasing id*)arg; // expected-error {{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}}
-  (void)(id*)arg; // expected-error {{pointer to non-const type 'id' with no explicit ownership}} expected-error {{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}}
+  (void)(id*)arg; // expected-error {{cast of an Objective-C pointer to '__strong id *' is disallowed with ARC}}
 
   (void)(__autoreleasing id**)voidp_val;
   (void)(void*)voidp_val;
@@ -53,3 +53,25 @@
   aip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__autoreleasing id *' is disallowed with ARC}}
   uip = vp; // expected-error{{implicit conversion of a non-Objective-C pointer type 'void *' to '__unsafe_unretained id *' is disallowed with ARC}}
 }
+
+typedef void (^Block)();
+typedef void (^Block_strong)() __strong;
+typedef void (^Block_autoreleasing)() __autoreleasing;
+
+ at class NSString;
+
+void ownership_transfer_in_cast(void *vp, Block *pblk) {
+  __strong NSString **sip = (NSString**)(__strong id *)vp;
+  __weak NSString **wip = (NSString**)(__weak id *)vp;
+  __autoreleasing id *aip = (id*)(__autoreleasing id *)vp;
+  __unsafe_unretained id *uip = (id*)(__unsafe_unretained id *)vp;
+
+  __strong id **sipp = (id**)(__strong id **)vp;
+  __weak id **wipp = (id**)(__weak id **)vp;
+  __autoreleasing id **aipp = (id**)(__autoreleasing id **)vp;
+  __unsafe_unretained id **uipp = (id**)(__unsafe_unretained id **)vp;
+
+  Block_strong blk_strong1;
+  Block_strong blk_strong2 = (Block)blk_strong1;
+  Block_autoreleasing *blk_auto = (Block*)pblk;
+}

Modified: cfe/trunk/test/SemaObjCXX/arc-type-conversion.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-type-conversion.mm?rev=134275&r1=134274&r2=134275&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-type-conversion.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-type-conversion.mm Fri Jul  1 17:22:59 2011
@@ -7,8 +7,7 @@
   (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}}
   (void)(id)arg;
   (void)(__autoreleasing id*)arg; // expected-error{{C-style cast from 'id' to '__autoreleasing id *' casts away qualifiers}}
-  (void)(id*)arg; // expected-error {{pointer to non-const type 'id' with no explicit ownership}} \
-  // expected-error{{C-style cast from 'id' to '__autoreleasing id *' casts away qualifiers}}
+  (void)(id*)arg; // expected-error{{C-style cast from 'id' to '__strong id *' casts away qualifiers}}
 
   (void)(__autoreleasing id**)voidp_val;
   (void)(void*)voidp_val;





More information about the cfe-commits mailing list