1 //===----- SemaObjC.cpp ---- Semantic Analysis for Objective-C ------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for Objective-C. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Sema/SemaObjC.h" 14 #include "clang/AST/ASTMutationListener.h" 15 #include "clang/AST/EvaluatedExprVisitor.h" 16 #include "clang/AST/StmtObjC.h" 17 #include "clang/Basic/DiagnosticSema.h" 18 #include "clang/Lex/Preprocessor.h" 19 #include "clang/Sema/Attr.h" 20 #include "clang/Sema/ParsedAttr.h" 21 #include "clang/Sema/ScopeInfo.h" 22 #include "clang/Sema/Sema.h" 23 #include "clang/Sema/TemplateDeduction.h" 24 #include "llvm/Support/ConvertUTF.h" 25 26 namespace clang { 27 28 SemaObjC::SemaObjC(Sema &S) 29 : SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr), 30 NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr), 31 ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), 32 ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), 33 DictionaryWithObjectsMethod(nullptr) {} 34 35 StmtResult SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, 36 Stmt *First, Expr *collection, 37 SourceLocation RParenLoc) { 38 ASTContext &Context = getASTContext(); 39 SemaRef.setFunctionHasBranchProtectedScope(); 40 41 ExprResult CollectionExprResult = 42 CheckObjCForCollectionOperand(ForLoc, collection); 43 44 if (First) { 45 QualType FirstType; 46 if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) { 47 if (!DS->isSingleDecl()) 48 return StmtError(Diag((*DS->decl_begin())->getLocation(), 49 diag::err_toomany_element_decls)); 50 51 VarDecl *D = dyn_cast<VarDecl>(DS->getSingleDecl()); 52 if (!D || D->isInvalidDecl()) 53 return StmtError(); 54 55 FirstType = D->getType(); 56 // C99 6.8.5p3: The declaration part of a 'for' statement shall only 57 // declare identifiers for objects having storage class 'auto' or 58 // 'register'. 59 if (!D->hasLocalStorage()) 60 return StmtError( 61 Diag(D->getLocation(), diag::err_non_local_variable_decl_in_for)); 62 63 // If the type contained 'auto', deduce the 'auto' to 'id'. 64 if (FirstType->getContainedAutoType()) { 65 SourceLocation Loc = D->getLocation(); 66 OpaqueValueExpr OpaqueId(Loc, Context.getObjCIdType(), VK_PRValue); 67 Expr *DeducedInit = &OpaqueId; 68 sema::TemplateDeductionInfo Info(Loc); 69 FirstType = QualType(); 70 TemplateDeductionResult Result = SemaRef.DeduceAutoType( 71 D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info); 72 if (Result != TemplateDeductionResult::Success && 73 Result != TemplateDeductionResult::AlreadyDiagnosed) 74 SemaRef.DiagnoseAutoDeductionFailure(D, DeducedInit); 75 if (FirstType.isNull()) { 76 D->setInvalidDecl(); 77 return StmtError(); 78 } 79 80 D->setType(FirstType); 81 82 if (!SemaRef.inTemplateInstantiation()) { 83 SourceLocation Loc = 84 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 85 Diag(Loc, diag::warn_auto_var_is_id) << D->getDeclName(); 86 } 87 } 88 89 } else { 90 Expr *FirstE = cast<Expr>(First); 91 if (!FirstE->isTypeDependent() && !FirstE->isLValue()) 92 return StmtError( 93 Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue) 94 << First->getSourceRange()); 95 96 FirstType = static_cast<Expr *>(First)->getType(); 97 if (FirstType.isConstQualified()) 98 Diag(ForLoc, diag::err_selector_element_const_type) 99 << FirstType << First->getSourceRange(); 100 } 101 if (!FirstType->isDependentType() && 102 !FirstType->isObjCObjectPointerType() && 103 !FirstType->isBlockPointerType()) 104 return StmtError(Diag(ForLoc, diag::err_selector_element_type) 105 << FirstType << First->getSourceRange()); 106 } 107 108 if (CollectionExprResult.isInvalid()) 109 return StmtError(); 110 111 CollectionExprResult = SemaRef.ActOnFinishFullExpr(CollectionExprResult.get(), 112 /*DiscardedValue*/ false); 113 if (CollectionExprResult.isInvalid()) 114 return StmtError(); 115 116 return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(), 117 nullptr, ForLoc, RParenLoc); 118 } 119 120 ExprResult SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, 121 Expr *collection) { 122 ASTContext &Context = getASTContext(); 123 if (!collection) 124 return ExprError(); 125 126 ExprResult result = SemaRef.CorrectDelayedTyposInExpr(collection); 127 if (!result.isUsable()) 128 return ExprError(); 129 collection = result.get(); 130 131 // Bail out early if we've got a type-dependent expression. 132 if (collection->isTypeDependent()) 133 return collection; 134 135 // Perform normal l-value conversion. 136 result = SemaRef.DefaultFunctionArrayLvalueConversion(collection); 137 if (result.isInvalid()) 138 return ExprError(); 139 collection = result.get(); 140 141 // The operand needs to have object-pointer type. 142 // TODO: should we do a contextual conversion? 143 const ObjCObjectPointerType *pointerType = 144 collection->getType()->getAs<ObjCObjectPointerType>(); 145 if (!pointerType) 146 return Diag(forLoc, diag::err_collection_expr_type) 147 << collection->getType() << collection->getSourceRange(); 148 149 // Check that the operand provides 150 // - countByEnumeratingWithState:objects:count: 151 const ObjCObjectType *objectType = pointerType->getObjectType(); 152 ObjCInterfaceDecl *iface = objectType->getInterface(); 153 154 // If we have a forward-declared type, we can't do this check. 155 // Under ARC, it is an error not to have a forward-declared class. 156 if (iface && 157 (getLangOpts().ObjCAutoRefCount 158 ? SemaRef.RequireCompleteType(forLoc, QualType(objectType, 0), 159 diag::err_arc_collection_forward, 160 collection) 161 : !SemaRef.isCompleteType(forLoc, QualType(objectType, 0)))) { 162 // Otherwise, if we have any useful type information, check that 163 // the type declares the appropriate method. 164 } else if (iface || !objectType->qual_empty()) { 165 const IdentifierInfo *selectorIdents[] = { 166 &Context.Idents.get("countByEnumeratingWithState"), 167 &Context.Idents.get("objects"), &Context.Idents.get("count")}; 168 Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]); 169 170 ObjCMethodDecl *method = nullptr; 171 172 // If there's an interface, look in both the public and private APIs. 173 if (iface) { 174 method = iface->lookupInstanceMethod(selector); 175 if (!method) 176 method = iface->lookupPrivateMethod(selector); 177 } 178 179 // Also check protocol qualifiers. 180 if (!method) 181 method = LookupMethodInQualifiedType(selector, pointerType, 182 /*instance*/ true); 183 184 // If we didn't find it anywhere, give up. 185 if (!method) { 186 Diag(forLoc, diag::warn_collection_expr_type) 187 << collection->getType() << selector << collection->getSourceRange(); 188 } 189 190 // TODO: check for an incompatible signature? 191 } 192 193 // Wrap up any cleanups in the expression. 194 return collection; 195 } 196 197 StmtResult SemaObjC::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) { 198 if (!S || !B) 199 return StmtError(); 200 ObjCForCollectionStmt *ForStmt = cast<ObjCForCollectionStmt>(S); 201 202 ForStmt->setBody(B); 203 return S; 204 } 205 206 StmtResult SemaObjC::ActOnObjCAtCatchStmt(SourceLocation AtLoc, 207 SourceLocation RParen, Decl *Parm, 208 Stmt *Body) { 209 ASTContext &Context = getASTContext(); 210 VarDecl *Var = cast_or_null<VarDecl>(Parm); 211 if (Var && Var->isInvalidDecl()) 212 return StmtError(); 213 214 return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body); 215 } 216 217 StmtResult SemaObjC::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) { 218 ASTContext &Context = getASTContext(); 219 return new (Context) ObjCAtFinallyStmt(AtLoc, Body); 220 } 221 222 StmtResult SemaObjC::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, 223 MultiStmtArg CatchStmts, 224 Stmt *Finally) { 225 ASTContext &Context = getASTContext(); 226 if (!getLangOpts().ObjCExceptions) 227 Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try"; 228 229 // Objective-C try is incompatible with SEH __try. 230 sema::FunctionScopeInfo *FSI = SemaRef.getCurFunction(); 231 if (FSI->FirstSEHTryLoc.isValid()) { 232 Diag(AtLoc, diag::err_mixing_cxx_try_seh_try) << 1; 233 Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'"; 234 } 235 236 FSI->setHasObjCTry(AtLoc); 237 unsigned NumCatchStmts = CatchStmts.size(); 238 return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(), 239 NumCatchStmts, Finally); 240 } 241 242 StmtResult SemaObjC::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { 243 ASTContext &Context = getASTContext(); 244 if (Throw) { 245 ExprResult Result = SemaRef.DefaultLvalueConversion(Throw); 246 if (Result.isInvalid()) 247 return StmtError(); 248 249 Result = 250 SemaRef.ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); 251 if (Result.isInvalid()) 252 return StmtError(); 253 Throw = Result.get(); 254 255 QualType ThrowType = Throw->getType(); 256 // Make sure the expression type is an ObjC pointer or "void *". 257 if (!ThrowType->isDependentType() && 258 !ThrowType->isObjCObjectPointerType()) { 259 const PointerType *PT = ThrowType->getAs<PointerType>(); 260 if (!PT || !PT->getPointeeType()->isVoidType()) 261 return StmtError(Diag(AtLoc, diag::err_objc_throw_expects_object) 262 << Throw->getType() << Throw->getSourceRange()); 263 } 264 } 265 266 return new (Context) ObjCAtThrowStmt(AtLoc, Throw); 267 } 268 269 StmtResult SemaObjC::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, 270 Scope *CurScope) { 271 if (!getLangOpts().ObjCExceptions) 272 Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw"; 273 274 if (!Throw) { 275 // @throw without an expression designates a rethrow (which must occur 276 // in the context of an @catch clause). 277 Scope *AtCatchParent = CurScope; 278 while (AtCatchParent && !AtCatchParent->isAtCatchScope()) 279 AtCatchParent = AtCatchParent->getParent(); 280 if (!AtCatchParent) 281 return StmtError(Diag(AtLoc, diag::err_rethrow_used_outside_catch)); 282 } 283 return BuildObjCAtThrowStmt(AtLoc, Throw); 284 } 285 286 ExprResult SemaObjC::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, 287 Expr *operand) { 288 ExprResult result = SemaRef.DefaultLvalueConversion(operand); 289 if (result.isInvalid()) 290 return ExprError(); 291 operand = result.get(); 292 293 // Make sure the expression type is an ObjC pointer or "void *". 294 QualType type = operand->getType(); 295 if (!type->isDependentType() && !type->isObjCObjectPointerType()) { 296 const PointerType *pointerType = type->getAs<PointerType>(); 297 if (!pointerType || !pointerType->getPointeeType()->isVoidType()) { 298 if (getLangOpts().CPlusPlus) { 299 if (SemaRef.RequireCompleteType(atLoc, type, 300 diag::err_incomplete_receiver_type)) 301 return Diag(atLoc, diag::err_objc_synchronized_expects_object) 302 << type << operand->getSourceRange(); 303 304 ExprResult result = 305 SemaRef.PerformContextuallyConvertToObjCPointer(operand); 306 if (result.isInvalid()) 307 return ExprError(); 308 if (!result.isUsable()) 309 return Diag(atLoc, diag::err_objc_synchronized_expects_object) 310 << type << operand->getSourceRange(); 311 312 operand = result.get(); 313 } else { 314 return Diag(atLoc, diag::err_objc_synchronized_expects_object) 315 << type << operand->getSourceRange(); 316 } 317 } 318 } 319 320 // The operand to @synchronized is a full-expression. 321 return SemaRef.ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); 322 } 323 324 StmtResult SemaObjC::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, 325 Expr *SyncExpr, 326 Stmt *SyncBody) { 327 ASTContext &Context = getASTContext(); 328 // We can't jump into or indirect-jump out of a @synchronized block. 329 SemaRef.setFunctionHasBranchProtectedScope(); 330 return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody); 331 } 332 333 StmtResult SemaObjC::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, 334 Stmt *Body) { 335 ASTContext &Context = getASTContext(); 336 SemaRef.setFunctionHasBranchProtectedScope(); 337 return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body); 338 } 339 340 TypeResult SemaObjC::actOnObjCProtocolQualifierType( 341 SourceLocation lAngleLoc, ArrayRef<Decl *> protocols, 342 ArrayRef<SourceLocation> protocolLocs, SourceLocation rAngleLoc) { 343 ASTContext &Context = getASTContext(); 344 // Form id<protocol-list>. 345 QualType Result = Context.getObjCObjectType( 346 Context.ObjCBuiltinIdTy, {}, 347 llvm::ArrayRef((ObjCProtocolDecl *const *)protocols.data(), 348 protocols.size()), 349 false); 350 Result = Context.getObjCObjectPointerType(Result); 351 352 TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result); 353 TypeLoc ResultTL = ResultTInfo->getTypeLoc(); 354 355 auto ObjCObjectPointerTL = ResultTL.castAs<ObjCObjectPointerTypeLoc>(); 356 ObjCObjectPointerTL.setStarLoc(SourceLocation()); // implicit 357 358 auto ObjCObjectTL = 359 ObjCObjectPointerTL.getPointeeLoc().castAs<ObjCObjectTypeLoc>(); 360 ObjCObjectTL.setHasBaseTypeAsWritten(false); 361 ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation()); 362 363 // No type arguments. 364 ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation()); 365 ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation()); 366 367 // Fill in protocol qualifiers. 368 ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc); 369 ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc); 370 for (unsigned i = 0, n = protocols.size(); i != n; ++i) 371 ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]); 372 373 // We're done. Return the completed type to the parser. 374 return SemaRef.CreateParsedType(Result, ResultTInfo); 375 } 376 377 TypeResult SemaObjC::actOnObjCTypeArgsAndProtocolQualifiers( 378 Scope *S, SourceLocation Loc, ParsedType BaseType, 379 SourceLocation TypeArgsLAngleLoc, ArrayRef<ParsedType> TypeArgs, 380 SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, 381 ArrayRef<Decl *> Protocols, ArrayRef<SourceLocation> ProtocolLocs, 382 SourceLocation ProtocolRAngleLoc) { 383 ASTContext &Context = getASTContext(); 384 TypeSourceInfo *BaseTypeInfo = nullptr; 385 QualType T = SemaRef.GetTypeFromParser(BaseType, &BaseTypeInfo); 386 if (T.isNull()) 387 return true; 388 389 // Handle missing type-source info. 390 if (!BaseTypeInfo) 391 BaseTypeInfo = Context.getTrivialTypeSourceInfo(T, Loc); 392 393 // Extract type arguments. 394 SmallVector<TypeSourceInfo *, 4> ActualTypeArgInfos; 395 for (unsigned i = 0, n = TypeArgs.size(); i != n; ++i) { 396 TypeSourceInfo *TypeArgInfo = nullptr; 397 QualType TypeArg = SemaRef.GetTypeFromParser(TypeArgs[i], &TypeArgInfo); 398 if (TypeArg.isNull()) { 399 ActualTypeArgInfos.clear(); 400 break; 401 } 402 403 assert(TypeArgInfo && "No type source info?"); 404 ActualTypeArgInfos.push_back(TypeArgInfo); 405 } 406 407 // Build the object type. 408 QualType Result = BuildObjCObjectType( 409 T, BaseTypeInfo->getTypeLoc().getSourceRange().getBegin(), 410 TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc, 411 ProtocolLAngleLoc, 412 llvm::ArrayRef((ObjCProtocolDecl *const *)Protocols.data(), 413 Protocols.size()), 414 ProtocolLocs, ProtocolRAngleLoc, 415 /*FailOnError=*/false, 416 /*Rebuilding=*/false); 417 418 if (Result == T) 419 return BaseType; 420 421 // Create source information for this type. 422 TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result); 423 TypeLoc ResultTL = ResultTInfo->getTypeLoc(); 424 425 // For id<Proto1, Proto2> or Class<Proto1, Proto2>, we'll have an 426 // object pointer type. Fill in source information for it. 427 if (auto ObjCObjectPointerTL = ResultTL.getAs<ObjCObjectPointerTypeLoc>()) { 428 // The '*' is implicit. 429 ObjCObjectPointerTL.setStarLoc(SourceLocation()); 430 ResultTL = ObjCObjectPointerTL.getPointeeLoc(); 431 } 432 433 if (auto OTPTL = ResultTL.getAs<ObjCTypeParamTypeLoc>()) { 434 // Protocol qualifier information. 435 if (OTPTL.getNumProtocols() > 0) { 436 assert(OTPTL.getNumProtocols() == Protocols.size()); 437 OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc); 438 OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc); 439 for (unsigned i = 0, n = Protocols.size(); i != n; ++i) 440 OTPTL.setProtocolLoc(i, ProtocolLocs[i]); 441 } 442 443 // We're done. Return the completed type to the parser. 444 return SemaRef.CreateParsedType(Result, ResultTInfo); 445 } 446 447 auto ObjCObjectTL = ResultTL.castAs<ObjCObjectTypeLoc>(); 448 449 // Type argument information. 450 if (ObjCObjectTL.getNumTypeArgs() > 0) { 451 assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size()); 452 ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc); 453 ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc); 454 for (unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i) 455 ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]); 456 } else { 457 ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation()); 458 ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation()); 459 } 460 461 // Protocol qualifier information. 462 if (ObjCObjectTL.getNumProtocols() > 0) { 463 assert(ObjCObjectTL.getNumProtocols() == Protocols.size()); 464 ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc); 465 ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc); 466 for (unsigned i = 0, n = Protocols.size(); i != n; ++i) 467 ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]); 468 } else { 469 ObjCObjectTL.setProtocolLAngleLoc(SourceLocation()); 470 ObjCObjectTL.setProtocolRAngleLoc(SourceLocation()); 471 } 472 473 // Base type. 474 ObjCObjectTL.setHasBaseTypeAsWritten(true); 475 if (ObjCObjectTL.getType() == T) 476 ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->getTypeLoc()); 477 else 478 ObjCObjectTL.getBaseLoc().initialize(Context, Loc); 479 480 // We're done. Return the completed type to the parser. 481 return SemaRef.CreateParsedType(Result, ResultTInfo); 482 } 483 484 QualType SemaObjC::BuildObjCTypeParamType( 485 const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, 486 ArrayRef<ObjCProtocolDecl *> Protocols, 487 ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc, 488 bool FailOnError) { 489 ASTContext &Context = getASTContext(); 490 QualType Result = QualType(Decl->getTypeForDecl(), 0); 491 if (!Protocols.empty()) { 492 bool HasError; 493 Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError); 494 if (HasError) { 495 Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers) 496 << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); 497 if (FailOnError) 498 Result = QualType(); 499 } 500 if (FailOnError && Result.isNull()) 501 return QualType(); 502 } 503 504 return Result; 505 } 506 507 /// Apply Objective-C type arguments to the given type. 508 static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, 509 ArrayRef<TypeSourceInfo *> typeArgs, 510 SourceRange typeArgsRange, bool failOnError, 511 bool rebuilding) { 512 // We can only apply type arguments to an Objective-C class type. 513 const auto *objcObjectType = type->getAs<ObjCObjectType>(); 514 if (!objcObjectType || !objcObjectType->getInterface()) { 515 S.Diag(loc, diag::err_objc_type_args_non_class) << type << typeArgsRange; 516 517 if (failOnError) 518 return QualType(); 519 return type; 520 } 521 522 // The class type must be parameterized. 523 ObjCInterfaceDecl *objcClass = objcObjectType->getInterface(); 524 ObjCTypeParamList *typeParams = objcClass->getTypeParamList(); 525 if (!typeParams) { 526 S.Diag(loc, diag::err_objc_type_args_non_parameterized_class) 527 << objcClass->getDeclName() << FixItHint::CreateRemoval(typeArgsRange); 528 529 if (failOnError) 530 return QualType(); 531 532 return type; 533 } 534 535 // The type must not already be specialized. 536 if (objcObjectType->isSpecialized()) { 537 S.Diag(loc, diag::err_objc_type_args_specialized_class) 538 << type << FixItHint::CreateRemoval(typeArgsRange); 539 540 if (failOnError) 541 return QualType(); 542 543 return type; 544 } 545 546 // Check the type arguments. 547 SmallVector<QualType, 4> finalTypeArgs; 548 unsigned numTypeParams = typeParams->size(); 549 bool anyPackExpansions = false; 550 for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) { 551 TypeSourceInfo *typeArgInfo = typeArgs[i]; 552 QualType typeArg = typeArgInfo->getType(); 553 554 // Type arguments cannot have explicit qualifiers or nullability. 555 // We ignore indirect sources of these, e.g. behind typedefs or 556 // template arguments. 557 if (TypeLoc qual = typeArgInfo->getTypeLoc().findExplicitQualifierLoc()) { 558 bool diagnosed = false; 559 SourceRange rangeToRemove; 560 if (auto attr = qual.getAs<AttributedTypeLoc>()) { 561 rangeToRemove = attr.getLocalSourceRange(); 562 if (attr.getTypePtr()->getImmediateNullability()) { 563 typeArg = attr.getTypePtr()->getModifiedType(); 564 S.Diag(attr.getBeginLoc(), 565 diag::err_objc_type_arg_explicit_nullability) 566 << typeArg << FixItHint::CreateRemoval(rangeToRemove); 567 diagnosed = true; 568 } 569 } 570 571 // When rebuilding, qualifiers might have gotten here through a 572 // final substitution. 573 if (!rebuilding && !diagnosed) { 574 S.Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified) 575 << typeArg << typeArg.getQualifiers().getAsString() 576 << FixItHint::CreateRemoval(rangeToRemove); 577 } 578 } 579 580 // Remove qualifiers even if they're non-local. 581 typeArg = typeArg.getUnqualifiedType(); 582 583 finalTypeArgs.push_back(typeArg); 584 585 if (typeArg->getAs<PackExpansionType>()) 586 anyPackExpansions = true; 587 588 // Find the corresponding type parameter, if there is one. 589 ObjCTypeParamDecl *typeParam = nullptr; 590 if (!anyPackExpansions) { 591 if (i < numTypeParams) { 592 typeParam = typeParams->begin()[i]; 593 } else { 594 // Too many arguments. 595 S.Diag(loc, diag::err_objc_type_args_wrong_arity) 596 << false << objcClass->getDeclName() << (unsigned)typeArgs.size() 597 << numTypeParams; 598 S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass; 599 600 if (failOnError) 601 return QualType(); 602 603 return type; 604 } 605 } 606 607 // Objective-C object pointer types must be substitutable for the bounds. 608 if (const auto *typeArgObjC = typeArg->getAs<ObjCObjectPointerType>()) { 609 // If we don't have a type parameter to match against, assume 610 // everything is fine. There was a prior pack expansion that 611 // means we won't be able to match anything. 612 if (!typeParam) { 613 assert(anyPackExpansions && "Too many arguments?"); 614 continue; 615 } 616 617 // Retrieve the bound. 618 QualType bound = typeParam->getUnderlyingType(); 619 const auto *boundObjC = bound->castAs<ObjCObjectPointerType>(); 620 621 // Determine whether the type argument is substitutable for the bound. 622 if (typeArgObjC->isObjCIdType()) { 623 // When the type argument is 'id', the only acceptable type 624 // parameter bound is 'id'. 625 if (boundObjC->isObjCIdType()) 626 continue; 627 } else if (S.Context.canAssignObjCInterfaces(boundObjC, typeArgObjC)) { 628 // Otherwise, we follow the assignability rules. 629 continue; 630 } 631 632 // Diagnose the mismatch. 633 S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), 634 diag::err_objc_type_arg_does_not_match_bound) 635 << typeArg << bound << typeParam->getDeclName(); 636 S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) 637 << typeParam->getDeclName(); 638 639 if (failOnError) 640 return QualType(); 641 642 return type; 643 } 644 645 // Block pointer types are permitted for unqualified 'id' bounds. 646 if (typeArg->isBlockPointerType()) { 647 // If we don't have a type parameter to match against, assume 648 // everything is fine. There was a prior pack expansion that 649 // means we won't be able to match anything. 650 if (!typeParam) { 651 assert(anyPackExpansions && "Too many arguments?"); 652 continue; 653 } 654 655 // Retrieve the bound. 656 QualType bound = typeParam->getUnderlyingType(); 657 if (bound->isBlockCompatibleObjCPointerType(S.Context)) 658 continue; 659 660 // Diagnose the mismatch. 661 S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), 662 diag::err_objc_type_arg_does_not_match_bound) 663 << typeArg << bound << typeParam->getDeclName(); 664 S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) 665 << typeParam->getDeclName(); 666 667 if (failOnError) 668 return QualType(); 669 670 return type; 671 } 672 673 // Types that have __attribute__((NSObject)) are permitted. 674 if (typeArg->isObjCNSObjectType()) { 675 continue; 676 } 677 678 // Dependent types will be checked at instantiation time. 679 if (typeArg->isDependentType()) { 680 continue; 681 } 682 683 // Diagnose non-id-compatible type arguments. 684 S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), 685 diag::err_objc_type_arg_not_id_compatible) 686 << typeArg << typeArgInfo->getTypeLoc().getSourceRange(); 687 688 if (failOnError) 689 return QualType(); 690 691 return type; 692 } 693 694 // Make sure we didn't have the wrong number of arguments. 695 if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) { 696 S.Diag(loc, diag::err_objc_type_args_wrong_arity) 697 << (typeArgs.size() < typeParams->size()) << objcClass->getDeclName() 698 << (unsigned)finalTypeArgs.size() << (unsigned)numTypeParams; 699 S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass; 700 701 if (failOnError) 702 return QualType(); 703 704 return type; 705 } 706 707 // Success. Form the specialized type. 708 return S.Context.getObjCObjectType(type, finalTypeArgs, {}, false); 709 } 710 711 QualType SemaObjC::BuildObjCObjectType( 712 QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, 713 ArrayRef<TypeSourceInfo *> TypeArgs, SourceLocation TypeArgsRAngleLoc, 714 SourceLocation ProtocolLAngleLoc, ArrayRef<ObjCProtocolDecl *> Protocols, 715 ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc, 716 bool FailOnError, bool Rebuilding) { 717 ASTContext &Context = getASTContext(); 718 QualType Result = BaseType; 719 if (!TypeArgs.empty()) { 720 Result = 721 applyObjCTypeArgs(SemaRef, Loc, Result, TypeArgs, 722 SourceRange(TypeArgsLAngleLoc, TypeArgsRAngleLoc), 723 FailOnError, Rebuilding); 724 if (FailOnError && Result.isNull()) 725 return QualType(); 726 } 727 728 if (!Protocols.empty()) { 729 bool HasError; 730 Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError); 731 if (HasError) { 732 Diag(Loc, diag::err_invalid_protocol_qualifiers) 733 << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); 734 if (FailOnError) 735 Result = QualType(); 736 } 737 if (FailOnError && Result.isNull()) 738 return QualType(); 739 } 740 741 return Result; 742 } 743 744 ParsedType SemaObjC::ActOnObjCInstanceType(SourceLocation Loc) { 745 ASTContext &Context = getASTContext(); 746 QualType T = Context.getObjCInstanceType(); 747 TypeSourceInfo *TInfo = Context.getTrivialTypeSourceInfo(T, Loc); 748 return SemaRef.CreateParsedType(T, TInfo); 749 } 750 751 //===--- CHECK: Objective-C retain cycles ----------------------------------// 752 753 namespace { 754 755 struct RetainCycleOwner { 756 VarDecl *Variable = nullptr; 757 SourceRange Range; 758 SourceLocation Loc; 759 bool Indirect = false; 760 761 RetainCycleOwner() = default; 762 763 void setLocsFrom(Expr *e) { 764 Loc = e->getExprLoc(); 765 Range = e->getSourceRange(); 766 } 767 }; 768 769 } // namespace 770 771 /// Consider whether capturing the given variable can possibly lead to 772 /// a retain cycle. 773 static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner) { 774 // In ARC, it's captured strongly iff the variable has __strong 775 // lifetime. In MRR, it's captured strongly if the variable is 776 // __block and has an appropriate type. 777 if (var->getType().getObjCLifetime() != Qualifiers::OCL_Strong) 778 return false; 779 780 owner.Variable = var; 781 if (ref) 782 owner.setLocsFrom(ref); 783 return true; 784 } 785 786 static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { 787 while (true) { 788 e = e->IgnoreParens(); 789 if (CastExpr *cast = dyn_cast<CastExpr>(e)) { 790 switch (cast->getCastKind()) { 791 case CK_BitCast: 792 case CK_LValueBitCast: 793 case CK_LValueToRValue: 794 case CK_ARCReclaimReturnedObject: 795 e = cast->getSubExpr(); 796 continue; 797 798 default: 799 return false; 800 } 801 } 802 803 if (ObjCIvarRefExpr *ref = dyn_cast<ObjCIvarRefExpr>(e)) { 804 ObjCIvarDecl *ivar = ref->getDecl(); 805 if (ivar->getType().getObjCLifetime() != Qualifiers::OCL_Strong) 806 return false; 807 808 // Try to find a retain cycle in the base. 809 if (!findRetainCycleOwner(S, ref->getBase(), owner)) 810 return false; 811 812 if (ref->isFreeIvar()) 813 owner.setLocsFrom(ref); 814 owner.Indirect = true; 815 return true; 816 } 817 818 if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e)) { 819 VarDecl *var = dyn_cast<VarDecl>(ref->getDecl()); 820 if (!var) 821 return false; 822 return considerVariable(var, ref, owner); 823 } 824 825 if (MemberExpr *member = dyn_cast<MemberExpr>(e)) { 826 if (member->isArrow()) 827 return false; 828 829 // Don't count this as an indirect ownership. 830 e = member->getBase(); 831 continue; 832 } 833 834 if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) { 835 // Only pay attention to pseudo-objects on property references. 836 ObjCPropertyRefExpr *pre = dyn_cast<ObjCPropertyRefExpr>( 837 pseudo->getSyntacticForm()->IgnoreParens()); 838 if (!pre) 839 return false; 840 if (pre->isImplicitProperty()) 841 return false; 842 ObjCPropertyDecl *property = pre->getExplicitProperty(); 843 if (!property->isRetaining() && 844 !(property->getPropertyIvarDecl() && 845 property->getPropertyIvarDecl()->getType().getObjCLifetime() == 846 Qualifiers::OCL_Strong)) 847 return false; 848 849 owner.Indirect = true; 850 if (pre->isSuperReceiver()) { 851 owner.Variable = S.getCurMethodDecl()->getSelfDecl(); 852 if (!owner.Variable) 853 return false; 854 owner.Loc = pre->getLocation(); 855 owner.Range = pre->getSourceRange(); 856 return true; 857 } 858 e = const_cast<Expr *>( 859 cast<OpaqueValueExpr>(pre->getBase())->getSourceExpr()); 860 continue; 861 } 862 863 // Array ivars? 864 865 return false; 866 } 867 } 868 869 namespace { 870 871 struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> { 872 VarDecl *Variable; 873 Expr *Capturer = nullptr; 874 bool VarWillBeReased = false; 875 876 FindCaptureVisitor(ASTContext &Context, VarDecl *variable) 877 : EvaluatedExprVisitor<FindCaptureVisitor>(Context), Variable(variable) {} 878 879 void VisitDeclRefExpr(DeclRefExpr *ref) { 880 if (ref->getDecl() == Variable && !Capturer) 881 Capturer = ref; 882 } 883 884 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { 885 if (Capturer) 886 return; 887 Visit(ref->getBase()); 888 if (Capturer && ref->isFreeIvar()) 889 Capturer = ref; 890 } 891 892 void VisitBlockExpr(BlockExpr *block) { 893 // Look inside nested blocks 894 if (block->getBlockDecl()->capturesVariable(Variable)) 895 Visit(block->getBlockDecl()->getBody()); 896 } 897 898 void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) { 899 if (Capturer) 900 return; 901 if (OVE->getSourceExpr()) 902 Visit(OVE->getSourceExpr()); 903 } 904 905 void VisitBinaryOperator(BinaryOperator *BinOp) { 906 if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) 907 return; 908 Expr *LHS = BinOp->getLHS(); 909 if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) { 910 if (DRE->getDecl() != Variable) 911 return; 912 if (Expr *RHS = BinOp->getRHS()) { 913 RHS = RHS->IgnoreParenCasts(); 914 std::optional<llvm::APSInt> Value; 915 VarWillBeReased = 916 (RHS && (Value = RHS->getIntegerConstantExpr(Context)) && 917 *Value == 0); 918 } 919 } 920 } 921 }; 922 923 } // namespace 924 925 /// Check whether the given argument is a block which captures a 926 /// variable. 927 static Expr *findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner) { 928 assert(owner.Variable && owner.Loc.isValid()); 929 930 e = e->IgnoreParenCasts(); 931 932 // Look through [^{...} copy] and Block_copy(^{...}). 933 if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(e)) { 934 Selector Cmd = ME->getSelector(); 935 if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") { 936 e = ME->getInstanceReceiver(); 937 if (!e) 938 return nullptr; 939 e = e->IgnoreParenCasts(); 940 } 941 } else if (CallExpr *CE = dyn_cast<CallExpr>(e)) { 942 if (CE->getNumArgs() == 1) { 943 FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl()); 944 if (Fn) { 945 const IdentifierInfo *FnI = Fn->getIdentifier(); 946 if (FnI && FnI->isStr("_Block_copy")) { 947 e = CE->getArg(0)->IgnoreParenCasts(); 948 } 949 } 950 } 951 } 952 953 BlockExpr *block = dyn_cast<BlockExpr>(e); 954 if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable)) 955 return nullptr; 956 957 FindCaptureVisitor visitor(S.Context, owner.Variable); 958 visitor.Visit(block->getBlockDecl()->getBody()); 959 return visitor.VarWillBeReased ? nullptr : visitor.Capturer; 960 } 961 962 static void diagnoseRetainCycle(Sema &S, Expr *capturer, 963 RetainCycleOwner &owner) { 964 assert(capturer); 965 assert(owner.Variable && owner.Loc.isValid()); 966 967 S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle) 968 << owner.Variable << capturer->getSourceRange(); 969 S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner) 970 << owner.Indirect << owner.Range; 971 } 972 973 /// Check for a keyword selector that starts with the word 'add' or 974 /// 'set'. 975 static bool isSetterLikeSelector(Selector sel) { 976 if (sel.isUnarySelector()) 977 return false; 978 979 StringRef str = sel.getNameForSlot(0); 980 str = str.ltrim('_'); 981 if (str.starts_with("set")) 982 str = str.substr(3); 983 else if (str.starts_with("add")) { 984 // Specially allow 'addOperationWithBlock:'. 985 if (sel.getNumArgs() == 1 && str.starts_with("addOperationWithBlock")) 986 return false; 987 str = str.substr(3); 988 } else 989 return false; 990 991 if (str.empty()) 992 return true; 993 return !isLowercase(str.front()); 994 } 995 996 static std::optional<int> 997 GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { 998 bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( 999 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableArray); 1000 if (!IsMutableArray) { 1001 return std::nullopt; 1002 } 1003 1004 Selector Sel = Message->getSelector(); 1005 1006 std::optional<NSAPI::NSArrayMethodKind> MKOpt = 1007 S.NSAPIObj->getNSArrayMethodKind(Sel); 1008 if (!MKOpt) { 1009 return std::nullopt; 1010 } 1011 1012 NSAPI::NSArrayMethodKind MK = *MKOpt; 1013 1014 switch (MK) { 1015 case NSAPI::NSMutableArr_addObject: 1016 case NSAPI::NSMutableArr_insertObjectAtIndex: 1017 case NSAPI::NSMutableArr_setObjectAtIndexedSubscript: 1018 return 0; 1019 case NSAPI::NSMutableArr_replaceObjectAtIndex: 1020 return 1; 1021 1022 default: 1023 return std::nullopt; 1024 } 1025 1026 return std::nullopt; 1027 } 1028 1029 static std::optional<int> 1030 GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { 1031 bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( 1032 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableDictionary); 1033 if (!IsMutableDictionary) { 1034 return std::nullopt; 1035 } 1036 1037 Selector Sel = Message->getSelector(); 1038 1039 std::optional<NSAPI::NSDictionaryMethodKind> MKOpt = 1040 S.NSAPIObj->getNSDictionaryMethodKind(Sel); 1041 if (!MKOpt) { 1042 return std::nullopt; 1043 } 1044 1045 NSAPI::NSDictionaryMethodKind MK = *MKOpt; 1046 1047 switch (MK) { 1048 case NSAPI::NSMutableDict_setObjectForKey: 1049 case NSAPI::NSMutableDict_setValueForKey: 1050 case NSAPI::NSMutableDict_setObjectForKeyedSubscript: 1051 return 0; 1052 1053 default: 1054 return std::nullopt; 1055 } 1056 1057 return std::nullopt; 1058 } 1059 1060 static std::optional<int> GetNSSetArgumentIndex(SemaObjC &S, 1061 ObjCMessageExpr *Message) { 1062 bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( 1063 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableSet); 1064 1065 bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( 1066 Message->getReceiverInterface(), NSAPI::ClassId_NSMutableOrderedSet); 1067 if (!IsMutableSet && !IsMutableOrderedSet) { 1068 return std::nullopt; 1069 } 1070 1071 Selector Sel = Message->getSelector(); 1072 1073 std::optional<NSAPI::NSSetMethodKind> MKOpt = 1074 S.NSAPIObj->getNSSetMethodKind(Sel); 1075 if (!MKOpt) { 1076 return std::nullopt; 1077 } 1078 1079 NSAPI::NSSetMethodKind MK = *MKOpt; 1080 1081 switch (MK) { 1082 case NSAPI::NSMutableSet_addObject: 1083 case NSAPI::NSOrderedSet_setObjectAtIndex: 1084 case NSAPI::NSOrderedSet_setObjectAtIndexedSubscript: 1085 case NSAPI::NSOrderedSet_insertObjectAtIndex: 1086 return 0; 1087 case NSAPI::NSOrderedSet_replaceObjectAtIndexWithObject: 1088 return 1; 1089 } 1090 1091 return std::nullopt; 1092 } 1093 1094 void SemaObjC::CheckObjCCircularContainer(ObjCMessageExpr *Message) { 1095 if (!Message->isInstanceMessage()) { 1096 return; 1097 } 1098 1099 std::optional<int> ArgOpt; 1100 1101 if (!(ArgOpt = GetNSMutableArrayArgumentIndex(*this, Message)) && 1102 !(ArgOpt = GetNSMutableDictionaryArgumentIndex(*this, Message)) && 1103 !(ArgOpt = GetNSSetArgumentIndex(*this, Message))) { 1104 return; 1105 } 1106 1107 int ArgIndex = *ArgOpt; 1108 1109 Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts(); 1110 if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Arg)) { 1111 Arg = OE->getSourceExpr()->IgnoreImpCasts(); 1112 } 1113 1114 if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) { 1115 if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { 1116 if (ArgRE->isObjCSelfExpr()) { 1117 Diag(Message->getSourceRange().getBegin(), 1118 diag::warn_objc_circular_container) 1119 << ArgRE->getDecl() << StringRef("'super'"); 1120 } 1121 } 1122 } else { 1123 Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); 1124 1125 if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) { 1126 Receiver = OE->getSourceExpr()->IgnoreImpCasts(); 1127 } 1128 1129 if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) { 1130 if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { 1131 if (ReceiverRE->getDecl() == ArgRE->getDecl()) { 1132 ValueDecl *Decl = ReceiverRE->getDecl(); 1133 Diag(Message->getSourceRange().getBegin(), 1134 diag::warn_objc_circular_container) 1135 << Decl << Decl; 1136 if (!ArgRE->isObjCSelfExpr()) { 1137 Diag(Decl->getLocation(), 1138 diag::note_objc_circular_container_declared_here) 1139 << Decl; 1140 } 1141 } 1142 } 1143 } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) { 1144 if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) { 1145 if (IvarRE->getDecl() == IvarArgRE->getDecl()) { 1146 ObjCIvarDecl *Decl = IvarRE->getDecl(); 1147 Diag(Message->getSourceRange().getBegin(), 1148 diag::warn_objc_circular_container) 1149 << Decl << Decl; 1150 Diag(Decl->getLocation(), 1151 diag::note_objc_circular_container_declared_here) 1152 << Decl; 1153 } 1154 } 1155 } 1156 } 1157 } 1158 1159 /// Check a message send to see if it's likely to cause a retain cycle. 1160 void SemaObjC::checkRetainCycles(ObjCMessageExpr *msg) { 1161 // Only check instance methods whose selector looks like a setter. 1162 if (!msg->isInstanceMessage() || !isSetterLikeSelector(msg->getSelector())) 1163 return; 1164 1165 // Try to find a variable that the receiver is strongly owned by. 1166 RetainCycleOwner owner; 1167 if (msg->getReceiverKind() == ObjCMessageExpr::Instance) { 1168 if (!findRetainCycleOwner(SemaRef, msg->getInstanceReceiver(), owner)) 1169 return; 1170 } else { 1171 assert(msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); 1172 owner.Variable = SemaRef.getCurMethodDecl()->getSelfDecl(); 1173 owner.Loc = msg->getSuperLoc(); 1174 owner.Range = msg->getSuperLoc(); 1175 } 1176 1177 // Check whether the receiver is captured by any of the arguments. 1178 const ObjCMethodDecl *MD = msg->getMethodDecl(); 1179 for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) { 1180 if (Expr *capturer = findCapturingExpr(SemaRef, msg->getArg(i), owner)) { 1181 // noescape blocks should not be retained by the method. 1182 if (MD && MD->parameters()[i]->hasAttr<NoEscapeAttr>()) 1183 continue; 1184 return diagnoseRetainCycle(SemaRef, capturer, owner); 1185 } 1186 } 1187 } 1188 1189 /// Check a property assign to see if it's likely to cause a retain cycle. 1190 void SemaObjC::checkRetainCycles(Expr *receiver, Expr *argument) { 1191 RetainCycleOwner owner; 1192 if (!findRetainCycleOwner(SemaRef, receiver, owner)) 1193 return; 1194 1195 if (Expr *capturer = findCapturingExpr(SemaRef, argument, owner)) 1196 diagnoseRetainCycle(SemaRef, capturer, owner); 1197 } 1198 1199 void SemaObjC::checkRetainCycles(VarDecl *Var, Expr *Init) { 1200 RetainCycleOwner Owner; 1201 if (!considerVariable(Var, /*DeclRefExpr=*/nullptr, Owner)) 1202 return; 1203 1204 // Because we don't have an expression for the variable, we have to set the 1205 // location explicitly here. 1206 Owner.Loc = Var->getLocation(); 1207 Owner.Range = Var->getSourceRange(); 1208 1209 if (Expr *Capturer = findCapturingExpr(SemaRef, Init, Owner)) 1210 diagnoseRetainCycle(SemaRef, Capturer, Owner); 1211 } 1212 1213 /// CheckObjCString - Checks that the argument to the builtin 1214 /// CFString constructor is correct 1215 /// Note: It might also make sense to do the UTF-16 conversion here (would 1216 /// simplify the backend). 1217 bool SemaObjC::CheckObjCString(Expr *Arg) { 1218 Arg = Arg->IgnoreParenCasts(); 1219 StringLiteral *Literal = dyn_cast<StringLiteral>(Arg); 1220 1221 if (!Literal || !Literal->isOrdinary()) { 1222 Diag(Arg->getBeginLoc(), diag::err_cfstring_literal_not_string_constant) 1223 << Arg->getSourceRange(); 1224 return true; 1225 } 1226 1227 if (Literal->containsNonAsciiOrNull()) { 1228 StringRef String = Literal->getString(); 1229 unsigned NumBytes = String.size(); 1230 SmallVector<llvm::UTF16, 128> ToBuf(NumBytes); 1231 const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)String.data(); 1232 llvm::UTF16 *ToPtr = &ToBuf[0]; 1233 1234 llvm::ConversionResult Result = 1235 llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr, 1236 ToPtr + NumBytes, llvm::strictConversion); 1237 // Check for conversion failure. 1238 if (Result != llvm::conversionOK) 1239 Diag(Arg->getBeginLoc(), diag::warn_cfstring_truncated) 1240 << Arg->getSourceRange(); 1241 } 1242 return false; 1243 } 1244 1245 bool SemaObjC::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, 1246 ArrayRef<const Expr *> Args) { 1247 Sema::VariadicCallType CallType = 1248 Method->isVariadic() ? Sema::VariadicMethod : Sema::VariadicDoesNotApply; 1249 1250 SemaRef.checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args, 1251 /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), 1252 CallType); 1253 1254 SemaRef.CheckTCBEnforcement(lbrac, Method); 1255 1256 return false; 1257 } 1258 1259 const DeclContext *SemaObjC::getCurObjCLexicalContext() const { 1260 const DeclContext *DC = SemaRef.getCurLexicalContext(); 1261 // A category implicitly has the attribute of the interface. 1262 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) 1263 DC = CatD->getClassInterface(); 1264 return DC; 1265 } 1266 1267 /// Retrieve the identifier "NSError". 1268 IdentifierInfo *SemaObjC::getNSErrorIdent() { 1269 if (!Ident_NSError) 1270 Ident_NSError = SemaRef.PP.getIdentifierInfo("NSError"); 1271 1272 return Ident_NSError; 1273 } 1274 1275 void SemaObjC::ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl) { 1276 assert( 1277 IDecl->getLexicalParent() == SemaRef.CurContext && 1278 "The next DeclContext should be lexically contained in the current one."); 1279 SemaRef.CurContext = IDecl; 1280 } 1281 1282 void SemaObjC::ActOnObjCContainerFinishDefinition() { 1283 // Exit this scope of this interface definition. 1284 SemaRef.PopDeclContext(); 1285 } 1286 1287 void SemaObjC::ActOnObjCTemporaryExitContainerContext( 1288 ObjCContainerDecl *ObjCCtx) { 1289 assert(ObjCCtx == SemaRef.CurContext && "Mismatch of container contexts"); 1290 SemaRef.OriginalLexicalContext = ObjCCtx; 1291 ActOnObjCContainerFinishDefinition(); 1292 } 1293 1294 void SemaObjC::ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx) { 1295 ActOnObjCContainerStartDefinition(ObjCCtx); 1296 SemaRef.OriginalLexicalContext = nullptr; 1297 } 1298 1299 /// Find the protocol with the given name, if any. 1300 ObjCProtocolDecl *SemaObjC::LookupProtocol(IdentifierInfo *II, 1301 SourceLocation IdLoc, 1302 RedeclarationKind Redecl) { 1303 Decl *D = SemaRef.LookupSingleName(SemaRef.TUScope, II, IdLoc, 1304 Sema::LookupObjCProtocolName, Redecl); 1305 return cast_or_null<ObjCProtocolDecl>(D); 1306 } 1307 1308 /// Determine whether this is an Objective-C writeback conversion, 1309 /// used for parameter passing when performing automatic reference counting. 1310 /// 1311 /// \param FromType The type we're converting form. 1312 /// 1313 /// \param ToType The type we're converting to. 1314 /// 1315 /// \param ConvertedType The type that will be produced after applying 1316 /// this conversion. 1317 bool SemaObjC::isObjCWritebackConversion(QualType FromType, QualType ToType, 1318 QualType &ConvertedType) { 1319 ASTContext &Context = getASTContext(); 1320 if (!getLangOpts().ObjCAutoRefCount || 1321 Context.hasSameUnqualifiedType(FromType, ToType)) 1322 return false; 1323 1324 // Parameter must be a pointer to __autoreleasing (with no other qualifiers). 1325 QualType ToPointee; 1326 if (const PointerType *ToPointer = ToType->getAs<PointerType>()) 1327 ToPointee = ToPointer->getPointeeType(); 1328 else 1329 return false; 1330 1331 Qualifiers ToQuals = ToPointee.getQualifiers(); 1332 if (!ToPointee->isObjCLifetimeType() || 1333 ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing || 1334 !ToQuals.withoutObjCLifetime().empty()) 1335 return false; 1336 1337 // Argument must be a pointer to __strong to __weak. 1338 QualType FromPointee; 1339 if (const PointerType *FromPointer = FromType->getAs<PointerType>()) 1340 FromPointee = FromPointer->getPointeeType(); 1341 else 1342 return false; 1343 1344 Qualifiers FromQuals = FromPointee.getQualifiers(); 1345 if (!FromPointee->isObjCLifetimeType() || 1346 (FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong && 1347 FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak)) 1348 return false; 1349 1350 // Make sure that we have compatible qualifiers. 1351 FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing); 1352 if (!ToQuals.compatiblyIncludes(FromQuals)) 1353 return false; 1354 1355 // Remove qualifiers from the pointee type we're converting from; they 1356 // aren't used in the compatibility check belong, and we'll be adding back 1357 // qualifiers (with __autoreleasing) if the compatibility check succeeds. 1358 FromPointee = FromPointee.getUnqualifiedType(); 1359 1360 // The unqualified form of the pointee types must be compatible. 1361 ToPointee = ToPointee.getUnqualifiedType(); 1362 bool IncompatibleObjC; 1363 if (Context.typesAreCompatible(FromPointee, ToPointee)) 1364 FromPointee = ToPointee; 1365 else if (!SemaRef.isObjCPointerConversion(FromPointee, ToPointee, FromPointee, 1366 IncompatibleObjC)) 1367 return false; 1368 1369 /// Construct the type we're converting to, which is a pointer to 1370 /// __autoreleasing pointee. 1371 FromPointee = Context.getQualifiedType(FromPointee, FromQuals); 1372 ConvertedType = Context.getPointerType(FromPointee); 1373 return true; 1374 } 1375 1376 /// CheckSubscriptingKind - This routine decide what type 1377 /// of indexing represented by "FromE" is being done. 1378 SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) { 1379 // If the expression already has integral or enumeration type, we're golden. 1380 QualType T = FromE->getType(); 1381 if (T->isIntegralOrEnumerationType()) 1382 return SemaObjC::OS_Array; 1383 1384 // If we don't have a class type in C++, there's no way we can get an 1385 // expression of integral or enumeration type. 1386 const RecordType *RecordTy = T->getAs<RecordType>(); 1387 if (!RecordTy && (T->isObjCObjectPointerType() || T->isVoidPointerType())) 1388 // All other scalar cases are assumed to be dictionary indexing which 1389 // caller handles, with diagnostics if needed. 1390 return SemaObjC::OS_Dictionary; 1391 if (!getLangOpts().CPlusPlus || !RecordTy || RecordTy->isIncompleteType()) { 1392 // No indexing can be done. Issue diagnostics and quit. 1393 const Expr *IndexExpr = FromE->IgnoreParenImpCasts(); 1394 if (isa<StringLiteral>(IndexExpr)) 1395 Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer) 1396 << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); 1397 else 1398 Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) << T; 1399 return SemaObjC::OS_Error; 1400 } 1401 1402 // We must have a complete class type. 1403 if (SemaRef.RequireCompleteType(FromE->getExprLoc(), T, 1404 diag::err_objc_index_incomplete_class_type, 1405 FromE)) 1406 return SemaObjC::OS_Error; 1407 1408 // Look for a conversion to an integral, enumeration type, or 1409 // objective-C pointer type. 1410 int NoIntegrals = 0, NoObjCIdPointers = 0; 1411 SmallVector<CXXConversionDecl *, 4> ConversionDecls; 1412 1413 for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl()) 1414 ->getVisibleConversionFunctions()) { 1415 if (CXXConversionDecl *Conversion = 1416 dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) { 1417 QualType CT = Conversion->getConversionType().getNonReferenceType(); 1418 if (CT->isIntegralOrEnumerationType()) { 1419 ++NoIntegrals; 1420 ConversionDecls.push_back(Conversion); 1421 } else if (CT->isObjCIdType() || CT->isBlockPointerType()) { 1422 ++NoObjCIdPointers; 1423 ConversionDecls.push_back(Conversion); 1424 } 1425 } 1426 } 1427 if (NoIntegrals == 1 && NoObjCIdPointers == 0) 1428 return SemaObjC::OS_Array; 1429 if (NoIntegrals == 0 && NoObjCIdPointers == 1) 1430 return SemaObjC::OS_Dictionary; 1431 if (NoIntegrals == 0 && NoObjCIdPointers == 0) { 1432 // No conversion function was found. Issue diagnostic and return. 1433 Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) 1434 << FromE->getType(); 1435 return SemaObjC::OS_Error; 1436 } 1437 Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion) 1438 << FromE->getType(); 1439 for (unsigned int i = 0; i < ConversionDecls.size(); i++) 1440 Diag(ConversionDecls[i]->getLocation(), 1441 diag::note_conv_function_declared_at); 1442 1443 return SemaObjC::OS_Error; 1444 } 1445 1446 void SemaObjC::AddCFAuditedAttribute(Decl *D) { 1447 ASTContext &Context = getASTContext(); 1448 IdentifierInfo *Ident; 1449 SourceLocation Loc; 1450 std::tie(Ident, Loc) = SemaRef.PP.getPragmaARCCFCodeAuditedInfo(); 1451 if (!Loc.isValid()) 1452 return; 1453 1454 // Don't add a redundant or conflicting attribute. 1455 if (D->hasAttr<CFAuditedTransferAttr>() || 1456 D->hasAttr<CFUnknownTransferAttr>()) 1457 return; 1458 1459 AttributeCommonInfo Info(Ident, SourceRange(Loc), 1460 AttributeCommonInfo::Form::Pragma()); 1461 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info)); 1462 } 1463 1464 bool SemaObjC::isCFError(RecordDecl *RD) { 1465 // If we already know about CFError, test it directly. 1466 if (CFError) 1467 return CFError == RD; 1468 1469 // Check whether this is CFError, which we identify based on its bridge to 1470 // NSError. CFErrorRef used to be declared with "objc_bridge" but is now 1471 // declared with "objc_bridge_mutable", so look for either one of the two 1472 // attributes. 1473 if (RD->getTagKind() == TagTypeKind::Struct) { 1474 IdentifierInfo *bridgedType = nullptr; 1475 if (auto bridgeAttr = RD->getAttr<ObjCBridgeAttr>()) 1476 bridgedType = bridgeAttr->getBridgedType(); 1477 else if (auto bridgeAttr = RD->getAttr<ObjCBridgeMutableAttr>()) 1478 bridgedType = bridgeAttr->getBridgedType(); 1479 1480 if (bridgedType == getNSErrorIdent()) { 1481 CFError = RD; 1482 return true; 1483 } 1484 } 1485 1486 return false; 1487 } 1488 1489 bool SemaObjC::isNSStringType(QualType T, bool AllowNSAttributedString) { 1490 const auto *PT = T->getAs<ObjCObjectPointerType>(); 1491 if (!PT) 1492 return false; 1493 1494 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 1495 if (!Cls) 1496 return false; 1497 1498 IdentifierInfo *ClsName = Cls->getIdentifier(); 1499 1500 if (AllowNSAttributedString && 1501 ClsName == &getASTContext().Idents.get("NSAttributedString")) 1502 return true; 1503 // FIXME: Should we walk the chain of classes? 1504 return ClsName == &getASTContext().Idents.get("NSString") || 1505 ClsName == &getASTContext().Idents.get("NSMutableString"); 1506 } 1507 1508 bool SemaObjC::isCFStringType(QualType T) { 1509 const auto *PT = T->getAs<PointerType>(); 1510 if (!PT) 1511 return false; 1512 1513 const auto *RT = PT->getPointeeType()->getAs<RecordType>(); 1514 if (!RT) 1515 return false; 1516 1517 const RecordDecl *RD = RT->getDecl(); 1518 if (RD->getTagKind() != TagTypeKind::Struct) 1519 return false; 1520 1521 return RD->getIdentifier() == &getASTContext().Idents.get("__CFString"); 1522 } 1523 1524 static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) { 1525 // The IBOutlet/IBOutletCollection attributes only apply to instance 1526 // variables or properties of Objective-C classes. The outlet must also 1527 // have an object reference type. 1528 if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) { 1529 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 1530 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type) 1531 << AL << VD->getType() << 0; 1532 return false; 1533 } 1534 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) { 1535 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 1536 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type) 1537 << AL << PD->getType() << 1; 1538 return false; 1539 } 1540 } else { 1541 S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL; 1542 return false; 1543 } 1544 1545 return true; 1546 } 1547 1548 void SemaObjC::handleIBOutlet(Decl *D, const ParsedAttr &AL) { 1549 if (!checkIBOutletCommon(SemaRef, D, AL)) 1550 return; 1551 1552 D->addAttr(::new (getASTContext()) IBOutletAttr(getASTContext(), AL)); 1553 } 1554 1555 void SemaObjC::handleIBOutletCollection(Decl *D, const ParsedAttr &AL) { 1556 1557 ASTContext &Context = getASTContext(); 1558 // The iboutletcollection attribute can have zero or one arguments. 1559 if (AL.getNumArgs() > 1) { 1560 Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1; 1561 return; 1562 } 1563 1564 if (!checkIBOutletCommon(SemaRef, D, AL)) 1565 return; 1566 1567 ParsedType PT; 1568 1569 if (AL.hasParsedType()) 1570 PT = AL.getTypeArg(); 1571 else { 1572 PT = SemaRef.getTypeName( 1573 Context.Idents.get("NSObject"), AL.getLoc(), 1574 SemaRef.getScopeForContext(D->getDeclContext()->getParent())); 1575 if (!PT) { 1576 Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject"; 1577 return; 1578 } 1579 } 1580 1581 TypeSourceInfo *QTLoc = nullptr; 1582 QualType QT = SemaRef.GetTypeFromParser(PT, &QTLoc); 1583 if (!QTLoc) 1584 QTLoc = Context.getTrivialTypeSourceInfo(QT, AL.getLoc()); 1585 1586 // Diagnose use of non-object type in iboutletcollection attribute. 1587 // FIXME. Gnu attribute extension ignores use of builtin types in 1588 // attributes. So, __attribute__((iboutletcollection(char))) will be 1589 // treated as __attribute__((iboutletcollection())). 1590 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 1591 Diag(AL.getLoc(), QT->isBuiltinType() 1592 ? diag::err_iboutletcollection_builtintype 1593 : diag::err_iboutletcollection_type) 1594 << QT; 1595 return; 1596 } 1597 1598 D->addAttr(::new (Context) IBOutletCollectionAttr(Context, AL, QTLoc)); 1599 } 1600 1601 void SemaObjC::handleSuppresProtocolAttr(Decl *D, const ParsedAttr &AL) { 1602 if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) { 1603 Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition) 1604 << AL << AL.getRange(); 1605 return; 1606 } 1607 1608 D->addAttr(::new (getASTContext()) 1609 ObjCExplicitProtocolImplAttr(getASTContext(), AL)); 1610 } 1611 1612 void SemaObjC::handleDirectAttr(Decl *D, const ParsedAttr &AL) { 1613 // objc_direct cannot be set on methods declared in the context of a protocol 1614 if (isa<ObjCProtocolDecl>(D->getDeclContext())) { 1615 Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false; 1616 return; 1617 } 1618 1619 if (getLangOpts().ObjCRuntime.allowsDirectDispatch()) { 1620 handleSimpleAttribute<ObjCDirectAttr>(*this, D, AL); 1621 } else { 1622 Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL; 1623 } 1624 } 1625 1626 void SemaObjC::handleDirectMembersAttr(Decl *D, const ParsedAttr &AL) { 1627 if (getLangOpts().ObjCRuntime.allowsDirectDispatch()) { 1628 handleSimpleAttribute<ObjCDirectMembersAttr>(*this, D, AL); 1629 } else { 1630 Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL; 1631 } 1632 } 1633 1634 void SemaObjC::handleMethodFamilyAttr(Decl *D, const ParsedAttr &AL) { 1635 const auto *M = cast<ObjCMethodDecl>(D); 1636 if (!AL.isArgIdent(0)) { 1637 Diag(AL.getLoc(), diag::err_attribute_argument_n_type) 1638 << AL << 1 << AANT_ArgumentIdentifier; 1639 return; 1640 } 1641 1642 IdentifierLoc *IL = AL.getArgAsIdent(0); 1643 ObjCMethodFamilyAttr::FamilyKind F; 1644 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) { 1645 Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident; 1646 return; 1647 } 1648 1649 if (F == ObjCMethodFamilyAttr::OMF_init && 1650 !M->getReturnType()->isObjCObjectPointerType()) { 1651 Diag(M->getLocation(), diag::err_init_method_bad_return_type) 1652 << M->getReturnType(); 1653 // Ignore the attribute. 1654 return; 1655 } 1656 1657 D->addAttr(new (getASTContext()) 1658 ObjCMethodFamilyAttr(getASTContext(), AL, F)); 1659 } 1660 1661 void SemaObjC::handleNSObject(Decl *D, const ParsedAttr &AL) { 1662 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { 1663 QualType T = TD->getUnderlyingType(); 1664 if (!T->isCARCBridgableType()) { 1665 Diag(TD->getLocation(), diag::err_nsobject_attribute); 1666 return; 1667 } 1668 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) { 1669 QualType T = PD->getType(); 1670 if (!T->isCARCBridgableType()) { 1671 Diag(PD->getLocation(), diag::err_nsobject_attribute); 1672 return; 1673 } 1674 } else { 1675 // It is okay to include this attribute on properties, e.g.: 1676 // 1677 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 1678 // 1679 // In this case it follows tradition and suppresses an error in the above 1680 // case. 1681 Diag(D->getLocation(), diag::warn_nsobject_attribute); 1682 } 1683 D->addAttr(::new (getASTContext()) ObjCNSObjectAttr(getASTContext(), AL)); 1684 } 1685 1686 void SemaObjC::handleIndependentClass(Decl *D, const ParsedAttr &AL) { 1687 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { 1688 QualType T = TD->getUnderlyingType(); 1689 if (!T->isObjCObjectPointerType()) { 1690 Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute); 1691 return; 1692 } 1693 } else { 1694 Diag(D->getLocation(), diag::warn_independentclass_attribute); 1695 return; 1696 } 1697 D->addAttr(::new (getASTContext()) 1698 ObjCIndependentClassAttr(getASTContext(), AL)); 1699 } 1700 1701 void SemaObjC::handleBlocksAttr(Decl *D, const ParsedAttr &AL) { 1702 if (!AL.isArgIdent(0)) { 1703 Diag(AL.getLoc(), diag::err_attribute_argument_n_type) 1704 << AL << 1 << AANT_ArgumentIdentifier; 1705 return; 1706 } 1707 1708 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident; 1709 BlocksAttr::BlockType type; 1710 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) { 1711 Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II; 1712 return; 1713 } 1714 1715 D->addAttr(::new (getASTContext()) BlocksAttr(getASTContext(), AL, type)); 1716 } 1717 1718 static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT) { 1719 return QT->isDependentType() || QT->isObjCRetainableType(); 1720 } 1721 1722 static bool isValidSubjectOfNSAttribute(QualType QT) { 1723 return QT->isDependentType() || QT->isObjCObjectPointerType() || 1724 QT->isObjCNSObjectType(); 1725 } 1726 1727 static bool isValidSubjectOfCFAttribute(QualType QT) { 1728 return QT->isDependentType() || QT->isPointerType() || 1729 isValidSubjectOfNSAttribute(QT); 1730 } 1731 1732 static bool isValidSubjectOfOSAttribute(QualType QT) { 1733 if (QT->isDependentType()) 1734 return true; 1735 QualType PT = QT->getPointeeType(); 1736 return !PT.isNull() && PT->getAsCXXRecordDecl() != nullptr; 1737 } 1738 1739 void SemaObjC::AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, 1740 Sema::RetainOwnershipKind K, 1741 bool IsTemplateInstantiation) { 1742 ValueDecl *VD = cast<ValueDecl>(D); 1743 switch (K) { 1744 case Sema::RetainOwnershipKind::OS: 1745 handleSimpleAttributeOrDiagnose<OSConsumedAttr>( 1746 *this, VD, CI, isValidSubjectOfOSAttribute(VD->getType()), 1747 diag::warn_ns_attribute_wrong_parameter_type, 1748 /*ExtraArgs=*/CI.getRange(), "os_consumed", /*pointers*/ 1); 1749 return; 1750 case Sema::RetainOwnershipKind::NS: 1751 handleSimpleAttributeOrDiagnose<NSConsumedAttr>( 1752 *this, VD, CI, isValidSubjectOfNSAttribute(VD->getType()), 1753 1754 // These attributes are normally just advisory, but in ARC, ns_consumed 1755 // is significant. Allow non-dependent code to contain inappropriate 1756 // attributes even in ARC, but require template instantiations to be 1757 // set up correctly. 1758 ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount) 1759 ? diag::err_ns_attribute_wrong_parameter_type 1760 : diag::warn_ns_attribute_wrong_parameter_type), 1761 /*ExtraArgs=*/CI.getRange(), "ns_consumed", /*objc pointers*/ 0); 1762 return; 1763 case Sema::RetainOwnershipKind::CF: 1764 handleSimpleAttributeOrDiagnose<CFConsumedAttr>( 1765 *this, VD, CI, isValidSubjectOfCFAttribute(VD->getType()), 1766 diag::warn_ns_attribute_wrong_parameter_type, 1767 /*ExtraArgs=*/CI.getRange(), "cf_consumed", /*pointers*/ 1); 1768 return; 1769 } 1770 } 1771 1772 Sema::RetainOwnershipKind 1773 SemaObjC::parsedAttrToRetainOwnershipKind(const ParsedAttr &AL) { 1774 switch (AL.getKind()) { 1775 case ParsedAttr::AT_CFConsumed: 1776 case ParsedAttr::AT_CFReturnsRetained: 1777 case ParsedAttr::AT_CFReturnsNotRetained: 1778 return Sema::RetainOwnershipKind::CF; 1779 case ParsedAttr::AT_OSConsumesThis: 1780 case ParsedAttr::AT_OSConsumed: 1781 case ParsedAttr::AT_OSReturnsRetained: 1782 case ParsedAttr::AT_OSReturnsNotRetained: 1783 case ParsedAttr::AT_OSReturnsRetainedOnZero: 1784 case ParsedAttr::AT_OSReturnsRetainedOnNonZero: 1785 return Sema::RetainOwnershipKind::OS; 1786 case ParsedAttr::AT_NSConsumesSelf: 1787 case ParsedAttr::AT_NSConsumed: 1788 case ParsedAttr::AT_NSReturnsRetained: 1789 case ParsedAttr::AT_NSReturnsNotRetained: 1790 case ParsedAttr::AT_NSReturnsAutoreleased: 1791 return Sema::RetainOwnershipKind::NS; 1792 default: 1793 llvm_unreachable("Wrong argument supplied"); 1794 } 1795 } 1796 1797 bool SemaObjC::checkNSReturnsRetainedReturnType(SourceLocation Loc, 1798 QualType QT) { 1799 if (isValidSubjectOfNSReturnsRetainedAttribute(QT)) 1800 return false; 1801 1802 Diag(Loc, diag::warn_ns_attribute_wrong_return_type) 1803 << "'ns_returns_retained'" << 0 << 0; 1804 return true; 1805 } 1806 1807 /// \return whether the parameter is a pointer to OSObject pointer. 1808 bool SemaObjC::isValidOSObjectOutParameter(const Decl *D) { 1809 const auto *PVD = dyn_cast<ParmVarDecl>(D); 1810 if (!PVD) 1811 return false; 1812 QualType QT = PVD->getType(); 1813 QualType PT = QT->getPointeeType(); 1814 return !PT.isNull() && isValidSubjectOfOSAttribute(PT); 1815 } 1816 1817 void SemaObjC::handleXReturnsXRetainedAttr(Decl *D, const ParsedAttr &AL) { 1818 QualType ReturnType; 1819 Sema::RetainOwnershipKind K = parsedAttrToRetainOwnershipKind(AL); 1820 1821 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { 1822 ReturnType = MD->getReturnType(); 1823 } else if (getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 1824 (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) { 1825 return; // ignore: was handled as a type attribute 1826 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) { 1827 ReturnType = PD->getType(); 1828 } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 1829 ReturnType = FD->getReturnType(); 1830 } else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) { 1831 // Attributes on parameters are used for out-parameters, 1832 // passed as pointers-to-pointers. 1833 unsigned DiagID = K == Sema::RetainOwnershipKind::CF 1834 ? /*pointer-to-CF-pointer*/ 2 1835 : /*pointer-to-OSObject-pointer*/ 3; 1836 ReturnType = Param->getType()->getPointeeType(); 1837 if (ReturnType.isNull()) { 1838 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type) 1839 << AL << DiagID << AL.getRange(); 1840 return; 1841 } 1842 } else if (AL.isUsedAsTypeAttr()) { 1843 return; 1844 } else { 1845 AttributeDeclKind ExpectedDeclKind; 1846 switch (AL.getKind()) { 1847 default: 1848 llvm_unreachable("invalid ownership attribute"); 1849 case ParsedAttr::AT_NSReturnsRetained: 1850 case ParsedAttr::AT_NSReturnsAutoreleased: 1851 case ParsedAttr::AT_NSReturnsNotRetained: 1852 ExpectedDeclKind = ExpectedFunctionOrMethod; 1853 break; 1854 1855 case ParsedAttr::AT_OSReturnsRetained: 1856 case ParsedAttr::AT_OSReturnsNotRetained: 1857 case ParsedAttr::AT_CFReturnsRetained: 1858 case ParsedAttr::AT_CFReturnsNotRetained: 1859 ExpectedDeclKind = ExpectedFunctionMethodOrParameter; 1860 break; 1861 } 1862 Diag(D->getBeginLoc(), diag::warn_attribute_wrong_decl_type) 1863 << AL.getRange() << AL << AL.isRegularKeywordAttribute() 1864 << ExpectedDeclKind; 1865 return; 1866 } 1867 1868 bool TypeOK; 1869 bool Cf; 1870 unsigned ParmDiagID = 2; // Pointer-to-CF-pointer 1871 switch (AL.getKind()) { 1872 default: 1873 llvm_unreachable("invalid ownership attribute"); 1874 case ParsedAttr::AT_NSReturnsRetained: 1875 TypeOK = isValidSubjectOfNSReturnsRetainedAttribute(ReturnType); 1876 Cf = false; 1877 break; 1878 1879 case ParsedAttr::AT_NSReturnsAutoreleased: 1880 case ParsedAttr::AT_NSReturnsNotRetained: 1881 TypeOK = isValidSubjectOfNSAttribute(ReturnType); 1882 Cf = false; 1883 break; 1884 1885 case ParsedAttr::AT_CFReturnsRetained: 1886 case ParsedAttr::AT_CFReturnsNotRetained: 1887 TypeOK = isValidSubjectOfCFAttribute(ReturnType); 1888 Cf = true; 1889 break; 1890 1891 case ParsedAttr::AT_OSReturnsRetained: 1892 case ParsedAttr::AT_OSReturnsNotRetained: 1893 TypeOK = isValidSubjectOfOSAttribute(ReturnType); 1894 Cf = true; 1895 ParmDiagID = 3; // Pointer-to-OSObject-pointer 1896 break; 1897 } 1898 1899 if (!TypeOK) { 1900 if (AL.isUsedAsTypeAttr()) 1901 return; 1902 1903 if (isa<ParmVarDecl>(D)) { 1904 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type) 1905 << AL << ParmDiagID << AL.getRange(); 1906 } else { 1907 // Needs to be kept in sync with warn_ns_attribute_wrong_return_type. 1908 enum : unsigned { Function, Method, Property } SubjectKind = Function; 1909 if (isa<ObjCMethodDecl>(D)) 1910 SubjectKind = Method; 1911 else if (isa<ObjCPropertyDecl>(D)) 1912 SubjectKind = Property; 1913 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type) 1914 << AL << SubjectKind << Cf << AL.getRange(); 1915 } 1916 return; 1917 } 1918 1919 switch (AL.getKind()) { 1920 default: 1921 llvm_unreachable("invalid ownership attribute"); 1922 case ParsedAttr::AT_NSReturnsAutoreleased: 1923 handleSimpleAttribute<NSReturnsAutoreleasedAttr>(*this, D, AL); 1924 return; 1925 case ParsedAttr::AT_CFReturnsNotRetained: 1926 handleSimpleAttribute<CFReturnsNotRetainedAttr>(*this, D, AL); 1927 return; 1928 case ParsedAttr::AT_NSReturnsNotRetained: 1929 handleSimpleAttribute<NSReturnsNotRetainedAttr>(*this, D, AL); 1930 return; 1931 case ParsedAttr::AT_CFReturnsRetained: 1932 handleSimpleAttribute<CFReturnsRetainedAttr>(*this, D, AL); 1933 return; 1934 case ParsedAttr::AT_NSReturnsRetained: 1935 handleSimpleAttribute<NSReturnsRetainedAttr>(*this, D, AL); 1936 return; 1937 case ParsedAttr::AT_OSReturnsRetained: 1938 handleSimpleAttribute<OSReturnsRetainedAttr>(*this, D, AL); 1939 return; 1940 case ParsedAttr::AT_OSReturnsNotRetained: 1941 handleSimpleAttribute<OSReturnsNotRetainedAttr>(*this, D, AL); 1942 return; 1943 }; 1944 } 1945 1946 void SemaObjC::handleReturnsInnerPointerAttr(Decl *D, const ParsedAttr &Attrs) { 1947 const int EP_ObjCMethod = 1; 1948 const int EP_ObjCProperty = 2; 1949 1950 SourceLocation loc = Attrs.getLoc(); 1951 QualType resultType; 1952 if (isa<ObjCMethodDecl>(D)) 1953 resultType = cast<ObjCMethodDecl>(D)->getReturnType(); 1954 else 1955 resultType = cast<ObjCPropertyDecl>(D)->getType(); 1956 1957 if (!resultType->isReferenceType() && 1958 (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 1959 Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type) 1960 << SourceRange(loc) << Attrs 1961 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty) 1962 << /*non-retainable pointer*/ 2; 1963 1964 // Drop the attribute. 1965 return; 1966 } 1967 1968 D->addAttr(::new (getASTContext()) 1969 ObjCReturnsInnerPointerAttr(getASTContext(), Attrs)); 1970 } 1971 1972 void SemaObjC::handleRequiresSuperAttr(Decl *D, const ParsedAttr &Attrs) { 1973 const auto *Method = cast<ObjCMethodDecl>(D); 1974 1975 const DeclContext *DC = Method->getDeclContext(); 1976 if (const auto *PDecl = dyn_cast_if_present<ObjCProtocolDecl>(DC)) { 1977 Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) 1978 << Attrs << 0; 1979 Diag(PDecl->getLocation(), diag::note_protocol_decl); 1980 return; 1981 } 1982 if (Method->getMethodFamily() == OMF_dealloc) { 1983 Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) 1984 << Attrs << 1; 1985 return; 1986 } 1987 1988 D->addAttr(::new (getASTContext()) 1989 ObjCRequiresSuperAttr(getASTContext(), Attrs)); 1990 } 1991 1992 void SemaObjC::handleNSErrorDomain(Decl *D, const ParsedAttr &Attr) { 1993 if (!isa<TagDecl>(D)) { 1994 Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0; 1995 return; 1996 } 1997 1998 IdentifierLoc *IdentLoc = 1999 Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr; 2000 if (!IdentLoc || !IdentLoc->Ident) { 2001 // Try to locate the argument directly. 2002 SourceLocation Loc = Attr.getLoc(); 2003 if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0)) 2004 Loc = Attr.getArgAsExpr(0)->getBeginLoc(); 2005 2006 Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0; 2007 return; 2008 } 2009 2010 // Verify that the identifier is a valid decl in the C decl namespace. 2011 LookupResult Result(SemaRef, DeclarationName(IdentLoc->Ident), 2012 SourceLocation(), 2013 Sema::LookupNameKind::LookupOrdinaryName); 2014 if (!SemaRef.LookupName(Result, SemaRef.TUScope) || 2015 !Result.getAsSingle<VarDecl>()) { 2016 Diag(IdentLoc->Loc, diag::err_nserrordomain_invalid_decl) 2017 << 1 << IdentLoc->Ident; 2018 return; 2019 } 2020 2021 D->addAttr(::new (getASTContext()) 2022 NSErrorDomainAttr(getASTContext(), Attr, IdentLoc->Ident)); 2023 } 2024 2025 void SemaObjC::handleBridgeAttr(Decl *D, const ParsedAttr &AL) { 2026 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr; 2027 2028 if (!Parm) { 2029 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0; 2030 return; 2031 } 2032 2033 // Typedefs only allow objc_bridge(id) and have some additional checking. 2034 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { 2035 if (!Parm->Ident->isStr("id")) { 2036 Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) << AL; 2037 return; 2038 } 2039 2040 // Only allow 'cv void *'. 2041 QualType T = TD->getUnderlyingType(); 2042 if (!T->isVoidPointerType()) { 2043 Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer); 2044 return; 2045 } 2046 } 2047 2048 D->addAttr(::new (getASTContext()) 2049 ObjCBridgeAttr(getASTContext(), AL, Parm->Ident)); 2050 } 2051 2052 void SemaObjC::handleBridgeMutableAttr(Decl *D, const ParsedAttr &AL) { 2053 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr; 2054 2055 if (!Parm) { 2056 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0; 2057 return; 2058 } 2059 2060 D->addAttr(::new (getASTContext()) 2061 ObjCBridgeMutableAttr(getASTContext(), AL, Parm->Ident)); 2062 } 2063 2064 void SemaObjC::handleBridgeRelatedAttr(Decl *D, const ParsedAttr &AL) { 2065 IdentifierInfo *RelatedClass = 2066 AL.isArgIdent(0) ? AL.getArgAsIdent(0)->Ident : nullptr; 2067 if (!RelatedClass) { 2068 Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0; 2069 return; 2070 } 2071 IdentifierInfo *ClassMethod = 2072 AL.getArgAsIdent(1) ? AL.getArgAsIdent(1)->Ident : nullptr; 2073 IdentifierInfo *InstanceMethod = 2074 AL.getArgAsIdent(2) ? AL.getArgAsIdent(2)->Ident : nullptr; 2075 D->addAttr(::new (getASTContext()) ObjCBridgeRelatedAttr( 2076 getASTContext(), AL, RelatedClass, ClassMethod, InstanceMethod)); 2077 } 2078 2079 void SemaObjC::handleDesignatedInitializer(Decl *D, const ParsedAttr &AL) { 2080 DeclContext *Ctx = D->getDeclContext(); 2081 2082 // This attribute can only be applied to methods in interfaces or class 2083 // extensions. 2084 if (!isa<ObjCInterfaceDecl>(Ctx) && 2085 !(isa<ObjCCategoryDecl>(Ctx) && 2086 cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) { 2087 Diag(D->getLocation(), diag::err_designated_init_attr_non_init); 2088 return; 2089 } 2090 2091 ObjCInterfaceDecl *IFace; 2092 if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx)) 2093 IFace = CatDecl->getClassInterface(); 2094 else 2095 IFace = cast<ObjCInterfaceDecl>(Ctx); 2096 2097 if (!IFace) 2098 return; 2099 2100 IFace->setHasDesignatedInitializers(); 2101 D->addAttr(::new (getASTContext()) 2102 ObjCDesignatedInitializerAttr(getASTContext(), AL)); 2103 } 2104 2105 void SemaObjC::handleRuntimeName(Decl *D, const ParsedAttr &AL) { 2106 StringRef MetaDataName; 2107 if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, MetaDataName)) 2108 return; 2109 D->addAttr(::new (getASTContext()) 2110 ObjCRuntimeNameAttr(getASTContext(), AL, MetaDataName)); 2111 } 2112 2113 // When a user wants to use objc_boxable with a union or struct 2114 // but they don't have access to the declaration (legacy/third-party code) 2115 // then they can 'enable' this feature with a typedef: 2116 // typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct; 2117 void SemaObjC::handleBoxable(Decl *D, const ParsedAttr &AL) { 2118 bool notify = false; 2119 2120 auto *RD = dyn_cast<RecordDecl>(D); 2121 if (RD && RD->getDefinition()) { 2122 RD = RD->getDefinition(); 2123 notify = true; 2124 } 2125 2126 if (RD) { 2127 ObjCBoxableAttr *BoxableAttr = 2128 ::new (getASTContext()) ObjCBoxableAttr(getASTContext(), AL); 2129 RD->addAttr(BoxableAttr); 2130 if (notify) { 2131 // we need to notify ASTReader/ASTWriter about 2132 // modification of existing declaration 2133 if (ASTMutationListener *L = SemaRef.getASTMutationListener()) 2134 L->AddedAttributeToRecord(BoxableAttr, RD); 2135 } 2136 } 2137 } 2138 2139 void SemaObjC::handleOwnershipAttr(Decl *D, const ParsedAttr &AL) { 2140 if (hasDeclarator(D)) 2141 return; 2142 2143 Diag(D->getBeginLoc(), diag::err_attribute_wrong_decl_type) 2144 << AL.getRange() << AL << AL.isRegularKeywordAttribute() 2145 << ExpectedVariable; 2146 } 2147 2148 void SemaObjC::handlePreciseLifetimeAttr(Decl *D, const ParsedAttr &AL) { 2149 const auto *VD = cast<ValueDecl>(D); 2150 QualType QT = VD->getType(); 2151 2152 if (!QT->isDependentType() && !QT->isObjCLifetimeType()) { 2153 Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type) << QT; 2154 return; 2155 } 2156 2157 Qualifiers::ObjCLifetime Lifetime = QT.getObjCLifetime(); 2158 2159 // If we have no lifetime yet, check the lifetime we're presumably 2160 // going to infer. 2161 if (Lifetime == Qualifiers::OCL_None && !QT->isDependentType()) 2162 Lifetime = QT->getObjCARCImplicitLifetime(); 2163 2164 switch (Lifetime) { 2165 case Qualifiers::OCL_None: 2166 assert(QT->isDependentType() && 2167 "didn't infer lifetime for non-dependent type?"); 2168 break; 2169 2170 case Qualifiers::OCL_Weak: // meaningful 2171 case Qualifiers::OCL_Strong: // meaningful 2172 break; 2173 2174 case Qualifiers::OCL_ExplicitNone: 2175 case Qualifiers::OCL_Autoreleasing: 2176 Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 2177 << (Lifetime == Qualifiers::OCL_Autoreleasing); 2178 break; 2179 } 2180 2181 D->addAttr(::new (getASTContext()) 2182 ObjCPreciseLifetimeAttr(getASTContext(), AL)); 2183 } 2184 2185 static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD, 2186 bool DiagnoseFailure) { 2187 QualType Ty = VD->getType(); 2188 if (!Ty->isObjCRetainableType()) { 2189 if (DiagnoseFailure) { 2190 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained) 2191 << 0; 2192 } 2193 return false; 2194 } 2195 2196 Qualifiers::ObjCLifetime LifetimeQual = Ty.getQualifiers().getObjCLifetime(); 2197 2198 // SemaObjC::inferObjCARCLifetime must run after processing decl attributes 2199 // (because __block lowers to an attribute), so if the lifetime hasn't been 2200 // explicitly specified, infer it locally now. 2201 if (LifetimeQual == Qualifiers::OCL_None) 2202 LifetimeQual = Ty->getObjCARCImplicitLifetime(); 2203 2204 // The attributes only really makes sense for __strong variables; ignore any 2205 // attempts to annotate a parameter with any other lifetime qualifier. 2206 if (LifetimeQual != Qualifiers::OCL_Strong) { 2207 if (DiagnoseFailure) { 2208 S.Diag(VD->getBeginLoc(), diag::warn_ignored_objc_externally_retained) 2209 << 1; 2210 } 2211 return false; 2212 } 2213 2214 // Tampering with the type of a VarDecl here is a bit of a hack, but we need 2215 // to ensure that the variable is 'const' so that we can error on 2216 // modification, which can otherwise over-release. 2217 VD->setType(Ty.withConst()); 2218 VD->setARCPseudoStrong(true); 2219 return true; 2220 } 2221 2222 void SemaObjC::handleExternallyRetainedAttr(Decl *D, const ParsedAttr &AL) { 2223 if (auto *VD = dyn_cast<VarDecl>(D)) { 2224 assert(!isa<ParmVarDecl>(VD) && "should be diagnosed automatically"); 2225 if (!VD->hasLocalStorage()) { 2226 Diag(D->getBeginLoc(), diag::warn_ignored_objc_externally_retained) << 0; 2227 return; 2228 } 2229 2230 if (!tryMakeVariablePseudoStrong(SemaRef, VD, /*DiagnoseFailure=*/true)) 2231 return; 2232 2233 handleSimpleAttribute<ObjCExternallyRetainedAttr>(*this, D, AL); 2234 return; 2235 } 2236 2237 // If D is a function-like declaration (method, block, or function), then we 2238 // make every parameter psuedo-strong. 2239 unsigned NumParams = 2240 hasFunctionProto(D) ? getFunctionOrMethodNumParams(D) : 0; 2241 for (unsigned I = 0; I != NumParams; ++I) { 2242 auto *PVD = const_cast<ParmVarDecl *>(getFunctionOrMethodParam(D, I)); 2243 QualType Ty = PVD->getType(); 2244 2245 // If a user wrote a parameter with __strong explicitly, then assume they 2246 // want "real" strong semantics for that parameter. This works because if 2247 // the parameter was written with __strong, then the strong qualifier will 2248 // be non-local. 2249 if (Ty.getLocalUnqualifiedType().getQualifiers().getObjCLifetime() == 2250 Qualifiers::OCL_Strong) 2251 continue; 2252 2253 tryMakeVariablePseudoStrong(SemaRef, PVD, /*DiagnoseFailure=*/false); 2254 } 2255 handleSimpleAttribute<ObjCExternallyRetainedAttr>(*this, D, AL); 2256 } 2257 2258 bool SemaObjC::GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx) { 2259 Sema::FormatStringInfo FSI; 2260 if ((SemaRef.GetFormatStringType(Format) == Sema::FST_NSString) && 2261 SemaRef.getFormatStringInfo(Format, false, true, &FSI)) { 2262 Idx = FSI.FormatIdx; 2263 return true; 2264 } 2265 return false; 2266 } 2267 2268 /// Diagnose use of %s directive in an NSString which is being passed 2269 /// as formatting string to formatting method. 2270 void SemaObjC::DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, 2271 Expr **Args, 2272 unsigned NumArgs) { 2273 unsigned Idx = 0; 2274 bool Format = false; 2275 ObjCStringFormatFamily SFFamily = FDecl->getObjCFStringFormattingFamily(); 2276 if (SFFamily == ObjCStringFormatFamily::SFF_CFString) { 2277 Idx = 2; 2278 Format = true; 2279 } else 2280 for (const auto *I : FDecl->specific_attrs<FormatAttr>()) { 2281 if (GetFormatNSStringIdx(I, Idx)) { 2282 Format = true; 2283 break; 2284 } 2285 } 2286 if (!Format || NumArgs <= Idx) 2287 return; 2288 const Expr *FormatExpr = Args[Idx]; 2289 if (const CStyleCastExpr *CSCE = dyn_cast<CStyleCastExpr>(FormatExpr)) 2290 FormatExpr = CSCE->getSubExpr(); 2291 const StringLiteral *FormatString; 2292 if (const ObjCStringLiteral *OSL = 2293 dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) 2294 FormatString = OSL->getString(); 2295 else 2296 FormatString = dyn_cast<StringLiteral>(FormatExpr->IgnoreParenImpCasts()); 2297 if (!FormatString) 2298 return; 2299 if (SemaRef.FormatStringHasSArg(FormatString)) { 2300 Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string) 2301 << "%s" << 1 << 1; 2302 Diag(FDecl->getLocation(), diag::note_entity_declared_at) 2303 << FDecl->getDeclName(); 2304 } 2305 } 2306 2307 bool SemaObjC::isSignedCharBool(QualType Ty) { 2308 return Ty->isSpecificBuiltinType(BuiltinType::SChar) && getLangOpts().ObjC && 2309 NSAPIObj->isObjCBOOLType(Ty); 2310 } 2311 2312 void SemaObjC::adornBoolConversionDiagWithTernaryFixit( 2313 Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder) { 2314 Expr *Ignored = SourceExpr->IgnoreImplicit(); 2315 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(Ignored)) 2316 Ignored = OVE->getSourceExpr(); 2317 bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) || 2318 isa<BinaryOperator>(Ignored) || 2319 isa<CXXOperatorCallExpr>(Ignored); 2320 SourceLocation EndLoc = SemaRef.getLocForEndOfToken(SourceExpr->getEndLoc()); 2321 if (NeedsParens) 2322 Builder << FixItHint::CreateInsertion(SourceExpr->getBeginLoc(), "(") 2323 << FixItHint::CreateInsertion(EndLoc, ")"); 2324 Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO"); 2325 } 2326 2327 /// Check a single element within a collection literal against the 2328 /// target element type. 2329 static void checkCollectionLiteralElement(Sema &S, QualType TargetElementType, 2330 Expr *Element, unsigned ElementKind) { 2331 // Skip a bitcast to 'id' or qualified 'id'. 2332 if (auto ICE = dyn_cast<ImplicitCastExpr>(Element)) { 2333 if (ICE->getCastKind() == CK_BitCast && 2334 ICE->getSubExpr()->getType()->getAs<ObjCObjectPointerType>()) 2335 Element = ICE->getSubExpr(); 2336 } 2337 2338 QualType ElementType = Element->getType(); 2339 ExprResult ElementResult(Element); 2340 if (ElementType->getAs<ObjCObjectPointerType>() && 2341 S.CheckSingleAssignmentConstraints(TargetElementType, ElementResult, 2342 false, false) != Sema::Compatible) { 2343 S.Diag(Element->getBeginLoc(), diag::warn_objc_collection_literal_element) 2344 << ElementType << ElementKind << TargetElementType 2345 << Element->getSourceRange(); 2346 } 2347 2348 if (auto ArrayLiteral = dyn_cast<ObjCArrayLiteral>(Element)) 2349 S.ObjC().checkArrayLiteral(TargetElementType, ArrayLiteral); 2350 else if (auto DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(Element)) 2351 S.ObjC().checkDictionaryLiteral(TargetElementType, DictionaryLiteral); 2352 } 2353 2354 /// Check an Objective-C array literal being converted to the given 2355 /// target type. 2356 void SemaObjC::checkArrayLiteral(QualType TargetType, 2357 ObjCArrayLiteral *ArrayLiteral) { 2358 if (!NSArrayDecl) 2359 return; 2360 2361 const auto *TargetObjCPtr = TargetType->getAs<ObjCObjectPointerType>(); 2362 if (!TargetObjCPtr) 2363 return; 2364 2365 if (TargetObjCPtr->isUnspecialized() || 2366 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() != 2367 NSArrayDecl->getCanonicalDecl()) 2368 return; 2369 2370 auto TypeArgs = TargetObjCPtr->getTypeArgs(); 2371 if (TypeArgs.size() != 1) 2372 return; 2373 2374 QualType TargetElementType = TypeArgs[0]; 2375 for (unsigned I = 0, N = ArrayLiteral->getNumElements(); I != N; ++I) { 2376 checkCollectionLiteralElement(SemaRef, TargetElementType, 2377 ArrayLiteral->getElement(I), 0); 2378 } 2379 } 2380 2381 void SemaObjC::checkDictionaryLiteral( 2382 QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral) { 2383 if (!NSDictionaryDecl) 2384 return; 2385 2386 const auto *TargetObjCPtr = TargetType->getAs<ObjCObjectPointerType>(); 2387 if (!TargetObjCPtr) 2388 return; 2389 2390 if (TargetObjCPtr->isUnspecialized() || 2391 TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() != 2392 NSDictionaryDecl->getCanonicalDecl()) 2393 return; 2394 2395 auto TypeArgs = TargetObjCPtr->getTypeArgs(); 2396 if (TypeArgs.size() != 2) 2397 return; 2398 2399 QualType TargetKeyType = TypeArgs[0]; 2400 QualType TargetObjectType = TypeArgs[1]; 2401 for (unsigned I = 0, N = DictionaryLiteral->getNumElements(); I != N; ++I) { 2402 auto Element = DictionaryLiteral->getKeyValueElement(I); 2403 checkCollectionLiteralElement(SemaRef, TargetKeyType, Element.Key, 1); 2404 checkCollectionLiteralElement(SemaRef, TargetObjectType, Element.Value, 2); 2405 } 2406 } 2407 2408 } // namespace clang 2409