diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
| commit | 486754660bb926339aefcf012a3f848592babb8b (patch) | |
| tree | ecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Sema/SemaExprObjC.cpp | |
| parent | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff) | |
Notes
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
| -rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index cd0c2c47ae4c..bf0ffeba06b2 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -141,7 +141,7 @@ ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){ return new (Context) ObjCStringLiteral(S, Ty, AtLoc); } -/// \brief Emits an error if the given method does not exist, or if the return +/// Emits an error if the given method does not exist, or if the return /// type is not an Objective-C object. static bool validateBoxingMethod(Sema &S, SourceLocation Loc, const ObjCInterfaceDecl *Class, @@ -165,7 +165,7 @@ static bool validateBoxingMethod(Sema &S, SourceLocation Loc, return true; } -/// \brief Maps ObjCLiteralKind to NSClassIdKindKind +/// Maps ObjCLiteralKind to NSClassIdKindKind static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( Sema::ObjCLiteralKind LiteralKind) { switch (LiteralKind) { @@ -189,7 +189,7 @@ static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( llvm_unreachable("LiteralKind can't be converted into a ClassKind"); } -/// \brief Validates ObjCInterfaceDecl availability. +/// Validates ObjCInterfaceDecl availability. /// ObjCInterfaceDecl, used to create ObjC literals, should be defined /// if clang not in a debugger mode. static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, @@ -211,7 +211,7 @@ static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, return true; } -/// \brief Looks up ObjCInterfaceDecl of a given NSClassIdKindKind. +/// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind. /// Used to create ObjC literals, such as NSDictionary (@{}), /// NSArray (@[]) and Boxed Expressions (@()) static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S, @@ -236,7 +236,7 @@ static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S, return ID; } -/// \brief Retrieve the NSNumber factory method that should be used to create +/// Retrieve the NSNumber factory method that should be used to create /// an Objective-C literal for the given type. static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, QualType NumberType, @@ -379,7 +379,7 @@ ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc, return BuildObjCNumericLiteral(AtLoc, Inner.get()); } -/// \brief Check that the given expression is a valid element of an Objective-C +/// Check that the given expression is a valid element of an Objective-C /// collection literal. static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, QualType T, @@ -1357,6 +1357,11 @@ QualType Sema::getMessageSendResultType(QualType ReceiverType, if (isClassMessage) return resultType; + // There is nothing left to do if the result type cannot have a nullability + // specifier. + if (!resultType->canHaveNullability()) + return resultType; + // Map the nullability of the result into a table index. unsigned receiverNullabilityIdx = 0; if (auto nullability = ReceiverType->getNullability(Context)) @@ -1613,6 +1618,11 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType, ParmVarDecl *param = Method->parameters()[i]; assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); + if (param->hasAttr<NoEscapeAttr>()) + if (auto *BE = dyn_cast<BlockExpr>( + argExpr->IgnoreParenNoopCasts(Context))) + BE->getBlockDecl()->setDoesNotEscape(); + // Strip the unbridged-cast placeholder expression off unless it's // a consumed argument. if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) && @@ -2319,7 +2329,7 @@ static void checkFoundationAPI(Sema &S, SourceLocation Loc, } } -/// \brief Diagnose use of %s directive in an NSString which is being passed +/// Diagnose use of %s directive in an NSString which is being passed /// as formatting string to formatting method. static void DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, @@ -2358,7 +2368,7 @@ DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, } } -/// \brief Build an Objective-C class message expression. +/// Build an Objective-C class message expression. /// /// This routine takes care of both normal class messages and /// class messages to the superclass. @@ -2403,11 +2413,12 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, << FixItHint::CreateInsertion(Loc, "["); LBracLoc = Loc; } - SourceLocation SelLoc; + ArrayRef<SourceLocation> SelectorSlotLocs; if (!SelectorLocs.empty() && SelectorLocs.front().isValid()) - SelLoc = SelectorLocs.front(); + SelectorSlotLocs = SelectorLocs; else - SelLoc = Loc; + SelectorSlotLocs = Loc; + SourceLocation SelLoc = SelectorSlotLocs.front(); if (ReceiverType->isDependentType()) { // If the receiver type is dependent, we can't type-check anything @@ -2432,7 +2443,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, assert(Class && "We don't know which class we're messaging?"); // objc++ diagnoses during typename annotation. if (!getLangOpts().CPlusPlus) - (void)DiagnoseUseOfDecl(Class, SelLoc); + (void)DiagnoseUseOfDecl(Class, SelectorSlotLocs); // Find the method we are messaging. if (!Method) { SourceRange TypeRange @@ -2457,7 +2468,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, if (!Method) Method = Class->lookupPrivateClassMethod(Sel); - if (Method && DiagnoseUseOfDecl(Method, SelLoc)) + if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs)) return ExprError(); } @@ -2581,7 +2592,7 @@ static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) { return false; } -/// \brief Build an Objective-C instance message expression. +/// Build an Objective-C instance message expression. /// /// This routine takes care of both normal instance messages and /// instance messages to the superclass instance. @@ -2627,11 +2638,12 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart(); SourceRange RecRange = SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange(); - SourceLocation SelLoc; + ArrayRef<SourceLocation> SelectorSlotLocs; if (!SelectorLocs.empty() && SelectorLocs.front().isValid()) - SelLoc = SelectorLocs.front(); + SelectorSlotLocs = SelectorLocs; else - SelLoc = Loc; + SelectorSlotLocs = Loc; + SourceLocation SelLoc = SelectorSlotLocs.front(); if (LBracLoc.isInvalid()) { Diag(Loc, diag::err_missing_open_square_message_send) @@ -2743,7 +2755,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (!AreMultipleMethodsInGlobalPool(Sel, Method, SourceRange(LBracLoc, RBracLoc), receiverIsIdLike, Methods)) - DiagnoseUseOfDecl(Method, SelLoc); + DiagnoseUseOfDecl(Method, SelectorSlotLocs); } } else if (ReceiverType->isObjCClassOrClassKindOfType() || ReceiverType->isObjCQualifiedClassType()) { @@ -2775,7 +2787,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (!Method) Method = ClassDecl->lookupPrivateClassMethod(Sel); } - if (Method && DiagnoseUseOfDecl(Method, SelLoc)) + if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs)) return ExprError(); } if (!Method) { @@ -2792,7 +2804,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // to select a better one. Method = Methods[0]; - // If we find an instance method, emit waring. + // If we find an instance method, emit warning. if (Method->isInstanceMethod()) { if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) { @@ -2822,7 +2834,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Method = LookupMethodInQualifiedType(Sel, QIdTy, true); if (!Method) Method = LookupMethodInQualifiedType(Sel, QIdTy, false); - if (Method && DiagnoseUseOfDecl(Method, SelLoc)) + if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs)) return ExprError(); } else if (const ObjCObjectPointerType *OCIType = ReceiverType->getAsObjCInterfacePointerType()) { @@ -2897,7 +2909,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } } - if (Method && DiagnoseUseOfDecl(Method, SelLoc, forwardClass)) + if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass)) return ExprError(); } else { // Reject other random receiver types (e.g. structs). @@ -3491,6 +3503,7 @@ static void addFixitForObjCARCConversion(Sema &S, // We handle C-style and implicit casts here. switch (CCK) { case Sema::CCK_ImplicitConversion: + case Sema::CCK_ForBuiltinOverloadedOp: case Sema::CCK_CStyleCast: case Sema::CCK_OtherCast: break; @@ -3644,11 +3657,13 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin()); SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc; + unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1; + // Bridge from an ARC type to a CF type. if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) { S.Diag(loc, diag::err_arc_cast_requires_bridge) - << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit + << convKindForDiag << 2 // of C pointer type << castExprType << unsigned(castType->isBlockPointerType()) // to ObjC|block type @@ -3690,7 +3705,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) { bool br = S.isKnownName("CFBridgingRetain"); S.Diag(loc, diag::err_arc_cast_requires_bridge) - << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit + << convKindForDiag << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type << castExprType << 2 // to C pointer type @@ -3727,7 +3742,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, } S.Diag(loc, diag::err_arc_mismatched_cast) - << (CCK != Sema::CCK_ImplicitConversion) + << !convKindForDiag << srcKind << castExprType << castType << castRange << castExpr->getSourceRange(); } @@ -4180,7 +4195,7 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, if (exprACTC == ACTC_indirectRetainable && castACTC == ACTC_voidPtr) return ACR_okay; if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr && - CCK != CCK_ImplicitConversion) + isCast(CCK)) return ACR_okay; switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) { @@ -4205,8 +4220,7 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, // If this is a non-implicit cast from id or block type to a // CoreFoundation type, delay complaining in case the cast is used // in an acceptable context. - if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && - CCK != CCK_ImplicitConversion) + if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && isCast(CCK)) return ACR_unbridged; // Issue a diagnostic about a missing @-sign when implicit casting a cstring @@ -4276,9 +4290,9 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) { assert(uo->getOpcode() == UO_Extension); Expr *sub = stripARCUnbridgedCast(uo->getSubExpr()); - return new (Context) UnaryOperator(sub, UO_Extension, sub->getType(), - sub->getValueKind(), sub->getObjectKind(), - uo->getOperatorLoc()); + return new (Context) + UnaryOperator(sub, UO_Extension, sub->getType(), sub->getValueKind(), + sub->getObjectKind(), uo->getOperatorLoc(), false); } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { assert(!gse->isResultDependent()); |
