xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
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 //
9 //  This file implements semantic analysis for Objective-C expressions.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/DeclObjC.h"
15 #include "clang/AST/ExprObjC.h"
16 #include "clang/AST/StmtVisitor.h"
17 #include "clang/AST/TypeLoc.h"
18 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
19 #include "clang/Basic/Builtins.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Edit/Commit.h"
22 #include "clang/Edit/Rewriters.h"
23 #include "clang/Lex/Preprocessor.h"
24 #include "clang/Sema/Initialization.h"
25 #include "clang/Sema/Lookup.h"
26 #include "clang/Sema/Scope.h"
27 #include "clang/Sema/ScopeInfo.h"
28 #include "clang/Sema/SemaInternal.h"
29 #include "clang/Sema/SemaObjC.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/Support/ConvertUTF.h"
32 #include <optional>
33 
34 using namespace clang;
35 using namespace sema;
36 using llvm::ArrayRef;
37 
ParseObjCStringLiteral(SourceLocation * AtLocs,ArrayRef<Expr * > Strings)38 ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs,
39                                             ArrayRef<Expr *> Strings) {
40   ASTContext &Context = getASTContext();
41   // Most ObjC strings are formed out of a single piece.  However, we *can*
42   // have strings formed out of multiple @ strings with multiple pptokens in
43   // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
44   // StringLiteral for ObjCStringLiteral to hold onto.
45   StringLiteral *S = cast<StringLiteral>(Strings[0]);
46 
47   // If we have a multi-part string, merge it all together.
48   if (Strings.size() != 1) {
49     // Concatenate objc strings.
50     SmallString<128> StrBuf;
51     SmallVector<SourceLocation, 8> StrLocs;
52 
53     for (Expr *E : Strings) {
54       S = cast<StringLiteral>(E);
55 
56       // ObjC strings can't be wide or UTF.
57       if (!S->isOrdinary()) {
58         Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
59             << S->getSourceRange();
60         return true;
61       }
62 
63       // Append the string.
64       StrBuf += S->getString();
65 
66       // Get the locations of the string tokens.
67       StrLocs.append(S->tokloc_begin(), S->tokloc_end());
68     }
69 
70     // Create the aggregate string with the appropriate content and location
71     // information.
72     const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());
73     assert(CAT && "String literal not of constant array type!");
74     QualType StrTy = Context.getConstantArrayType(
75         CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,
76         CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
77     S = StringLiteral::Create(Context, StrBuf, StringLiteralKind::Ordinary,
78                               /*Pascal=*/false, StrTy, &StrLocs[0],
79                               StrLocs.size());
80   }
81 
82   return BuildObjCStringLiteral(AtLocs[0], S);
83 }
84 
BuildObjCStringLiteral(SourceLocation AtLoc,StringLiteral * S)85 ExprResult SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc,
86                                             StringLiteral *S) {
87   ASTContext &Context = getASTContext();
88   // Verify that this composite string is acceptable for ObjC strings.
89   if (CheckObjCString(S))
90     return true;
91 
92   // Initialize the constant string interface lazily. This assumes
93   // the NSString interface is seen in this translation unit. Note: We
94   // don't use NSConstantString, since the runtime team considers this
95   // interface private (even though it appears in the header files).
96   QualType Ty = Context.getObjCConstantStringInterface();
97   if (!Ty.isNull()) {
98     Ty = Context.getObjCObjectPointerType(Ty);
99   } else if (getLangOpts().NoConstantCFStrings) {
100     IdentifierInfo *NSIdent=nullptr;
101     std::string StringClass(getLangOpts().ObjCConstantStringClass);
102 
103     if (StringClass.empty())
104       NSIdent = &Context.Idents.get("NSConstantString");
105     else
106       NSIdent = &Context.Idents.get(StringClass);
107 
108     NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc,
109                                              Sema::LookupOrdinaryName);
110     if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
111       Context.setObjCConstantStringInterface(StrIF);
112       Ty = Context.getObjCConstantStringInterface();
113       Ty = Context.getObjCObjectPointerType(Ty);
114     } else {
115       // If there is no NSConstantString interface defined then treat this
116       // as error and recover from it.
117       Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)
118           << NSIdent << S->getSourceRange();
119       Ty = Context.getObjCIdType();
120     }
121   } else {
122     IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
123     NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc,
124                                              Sema::LookupOrdinaryName);
125     if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
126       Context.setObjCConstantStringInterface(StrIF);
127       Ty = Context.getObjCConstantStringInterface();
128       Ty = Context.getObjCObjectPointerType(Ty);
129     } else {
130       // If there is no NSString interface defined, implicitly declare
131       // a @class NSString; and use that instead. This is to make sure
132       // type of an NSString literal is represented correctly, instead of
133       // being an 'id' type.
134       Ty = Context.getObjCNSStringType();
135       if (Ty.isNull()) {
136         ObjCInterfaceDecl *NSStringIDecl =
137           ObjCInterfaceDecl::Create (Context,
138                                      Context.getTranslationUnitDecl(),
139                                      SourceLocation(), NSIdent,
140                                      nullptr, nullptr, SourceLocation());
141         Ty = Context.getObjCInterfaceType(NSStringIDecl);
142         Context.setObjCNSStringType(Ty);
143       }
144       Ty = Context.getObjCObjectPointerType(Ty);
145     }
146   }
147 
148   return new (Context) ObjCStringLiteral(S, Ty, AtLoc);
149 }
150 
151 /// Emits an error if the given method does not exist, or if the return
152 /// type is not an Objective-C object.
validateBoxingMethod(Sema & S,SourceLocation Loc,const ObjCInterfaceDecl * Class,Selector Sel,const ObjCMethodDecl * Method)153 static bool validateBoxingMethod(Sema &S, SourceLocation Loc,
154                                  const ObjCInterfaceDecl *Class,
155                                  Selector Sel, const ObjCMethodDecl *Method) {
156   if (!Method) {
157     // FIXME: Is there a better way to avoid quotes than using getName()?
158     S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();
159     return false;
160   }
161 
162   // Make sure the return type is reasonable.
163   QualType ReturnType = Method->getReturnType();
164   if (!ReturnType->isObjCObjectPointerType()) {
165     S.Diag(Loc, diag::err_objc_literal_method_sig)
166       << Sel;
167     S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)
168       << ReturnType;
169     return false;
170   }
171 
172   return true;
173 }
174 
175 /// Maps ObjCLiteralKind to NSClassIdKindKind
176 static NSAPI::NSClassIdKindKind
ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind)177 ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind) {
178   switch (LiteralKind) {
179   case SemaObjC::LK_Array:
180     return NSAPI::ClassId_NSArray;
181   case SemaObjC::LK_Dictionary:
182     return NSAPI::ClassId_NSDictionary;
183   case SemaObjC::LK_Numeric:
184     return NSAPI::ClassId_NSNumber;
185   case SemaObjC::LK_String:
186     return NSAPI::ClassId_NSString;
187   case SemaObjC::LK_Boxed:
188     return NSAPI::ClassId_NSValue;
189 
190   // there is no corresponding matching
191   // between LK_None/LK_Block and NSClassIdKindKind
192   case SemaObjC::LK_Block:
193   case SemaObjC::LK_None:
194     break;
195   }
196   llvm_unreachable("LiteralKind can't be converted into a ClassKind");
197 }
198 
199 /// Validates ObjCInterfaceDecl availability.
200 /// ObjCInterfaceDecl, used to create ObjC literals, should be defined
201 /// if clang not in a debugger mode.
202 static bool
ValidateObjCLiteralInterfaceDecl(Sema & S,ObjCInterfaceDecl * Decl,SourceLocation Loc,SemaObjC::ObjCLiteralKind LiteralKind)203 ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,
204                                  SourceLocation Loc,
205                                  SemaObjC::ObjCLiteralKind LiteralKind) {
206   if (!Decl) {
207     NSAPI::NSClassIdKindKind Kind = ClassKindFromLiteralKind(LiteralKind);
208     IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(Kind);
209     S.Diag(Loc, diag::err_undeclared_objc_literal_class)
210       << II->getName() << LiteralKind;
211     return false;
212   } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
213     S.Diag(Loc, diag::err_undeclared_objc_literal_class)
214       << Decl->getName() << LiteralKind;
215     S.Diag(Decl->getLocation(), diag::note_forward_class);
216     return false;
217   }
218 
219   return true;
220 }
221 
222 /// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
223 /// Used to create ObjC literals, such as NSDictionary (@{}),
224 /// NSArray (@[]) and Boxed Expressions (@())
225 static ObjCInterfaceDecl *
LookupObjCInterfaceDeclForLiteral(Sema & S,SourceLocation Loc,SemaObjC::ObjCLiteralKind LiteralKind)226 LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc,
227                                   SemaObjC::ObjCLiteralKind LiteralKind) {
228   NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind);
229   IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(ClassKind);
230   NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc,
231                                      Sema::LookupOrdinaryName);
232   ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
233   if (!ID && S.getLangOpts().DebuggerObjCLiteral) {
234     ASTContext &Context = S.Context;
235     TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
236     ID = ObjCInterfaceDecl::Create (Context, TU, SourceLocation(), II,
237                                     nullptr, nullptr, SourceLocation());
238   }
239 
240   if (!ValidateObjCLiteralInterfaceDecl(S, ID, Loc, LiteralKind)) {
241     ID = nullptr;
242   }
243 
244   return ID;
245 }
246 
247 /// Retrieve the NSNumber factory method that should be used to create
248 /// an Objective-C literal for the given type.
getNSNumberFactoryMethod(SemaObjC & S,SourceLocation Loc,QualType NumberType,bool isLiteral=false,SourceRange R=SourceRange ())249 static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc,
250                                                 QualType NumberType,
251                                                 bool isLiteral = false,
252                                                 SourceRange R = SourceRange()) {
253   std::optional<NSAPI::NSNumberLiteralMethodKind> Kind =
254       S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
255 
256   if (!Kind) {
257     if (isLiteral) {
258       S.Diag(Loc, diag::err_invalid_nsnumber_type)
259         << NumberType << R;
260     }
261     return nullptr;
262   }
263 
264   // If we already looked up this method, we're done.
265   if (S.NSNumberLiteralMethods[*Kind])
266     return S.NSNumberLiteralMethods[*Kind];
267 
268   Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
269                                                         /*Instance=*/false);
270 
271   ASTContext &CX = S.SemaRef.Context;
272 
273   // Look up the NSNumber class, if we haven't done so already. It's cached
274   // in the Sema instance.
275   if (!S.NSNumberDecl) {
276     S.NSNumberDecl =
277         LookupObjCInterfaceDeclForLiteral(S.SemaRef, Loc, SemaObjC::LK_Numeric);
278     if (!S.NSNumberDecl) {
279       return nullptr;
280     }
281   }
282 
283   if (S.NSNumberPointer.isNull()) {
284     // generate the pointer to NSNumber type.
285     QualType NSNumberObject = CX.getObjCInterfaceType(S.NSNumberDecl);
286     S.NSNumberPointer = CX.getObjCObjectPointerType(NSNumberObject);
287   }
288 
289   // Look for the appropriate method within NSNumber.
290   ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);
291   if (!Method && S.getLangOpts().DebuggerObjCLiteral) {
292     // create a stub definition this NSNumber factory method.
293     TypeSourceInfo *ReturnTInfo = nullptr;
294     Method = ObjCMethodDecl::Create(
295         CX, SourceLocation(), SourceLocation(), Sel, S.NSNumberPointer,
296         ReturnTInfo, S.NSNumberDecl,
297         /*isInstance=*/false, /*isVariadic=*/false,
298         /*isPropertyAccessor=*/false,
299         /*isSynthesizedAccessorStub=*/false,
300         /*isImplicitlyDeclared=*/true,
301         /*isDefined=*/false, ObjCImplementationControl::Required,
302         /*HasRelatedResultType=*/false);
303     ParmVarDecl *value =
304         ParmVarDecl::Create(S.SemaRef.Context, Method, SourceLocation(),
305                             SourceLocation(), &CX.Idents.get("value"),
306                             NumberType, /*TInfo=*/nullptr, SC_None, nullptr);
307     Method->setMethodParams(S.SemaRef.Context, value, std::nullopt);
308   }
309 
310   if (!validateBoxingMethod(S.SemaRef, Loc, S.NSNumberDecl, Sel, Method))
311     return nullptr;
312 
313   // Note: if the parameter type is out-of-line, we'll catch it later in the
314   // implicit conversion.
315 
316   S.NSNumberLiteralMethods[*Kind] = Method;
317   return Method;
318 }
319 
320 /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
321 /// numeric literal expression. Type of the expression will be "NSNumber *".
BuildObjCNumericLiteral(SourceLocation AtLoc,Expr * Number)322 ExprResult SemaObjC::BuildObjCNumericLiteral(SourceLocation AtLoc,
323                                              Expr *Number) {
324   ASTContext &Context = getASTContext();
325   // Determine the type of the literal.
326   QualType NumberType = Number->getType();
327   if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {
328     // In C, character literals have type 'int'. That's not the type we want
329     // to use to determine the Objective-c literal kind.
330     switch (Char->getKind()) {
331     case CharacterLiteralKind::Ascii:
332     case CharacterLiteralKind::UTF8:
333       NumberType = Context.CharTy;
334       break;
335 
336     case CharacterLiteralKind::Wide:
337       NumberType = Context.getWideCharType();
338       break;
339 
340     case CharacterLiteralKind::UTF16:
341       NumberType = Context.Char16Ty;
342       break;
343 
344     case CharacterLiteralKind::UTF32:
345       NumberType = Context.Char32Ty;
346       break;
347     }
348   }
349 
350   // Look for the appropriate method within NSNumber.
351   // Construct the literal.
352   SourceRange NR(Number->getSourceRange());
353   ObjCMethodDecl *Method = getNSNumberFactoryMethod(*this, AtLoc, NumberType,
354                                                     true, NR);
355   if (!Method)
356     return ExprError();
357 
358   // Convert the number to the type that the parameter expects.
359   ParmVarDecl *ParamDecl = Method->parameters()[0];
360   InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
361                                                                     ParamDecl);
362   ExprResult ConvertedNumber =
363       SemaRef.PerformCopyInitialization(Entity, SourceLocation(), Number);
364   if (ConvertedNumber.isInvalid())
365     return ExprError();
366   Number = ConvertedNumber.get();
367 
368   // Use the effective source range of the literal, including the leading '@'.
369   return SemaRef.MaybeBindToTemporary(new (Context) ObjCBoxedExpr(
370       Number, NSNumberPointer, Method, SourceRange(AtLoc, NR.getEnd())));
371 }
372 
ActOnObjCBoolLiteral(SourceLocation AtLoc,SourceLocation ValueLoc,bool Value)373 ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation AtLoc,
374                                           SourceLocation ValueLoc, bool Value) {
375   ASTContext &Context = getASTContext();
376   ExprResult Inner;
377   if (getLangOpts().CPlusPlus) {
378     Inner = SemaRef.ActOnCXXBoolLiteral(ValueLoc,
379                                         Value ? tok::kw_true : tok::kw_false);
380   } else {
381     // C doesn't actually have a way to represent literal values of type
382     // _Bool. So, we'll use 0/1 and implicit cast to _Bool.
383     Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0);
384     Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy,
385                                       CK_IntegralToBoolean);
386   }
387 
388   return BuildObjCNumericLiteral(AtLoc, Inner.get());
389 }
390 
391 /// Check that the given expression is a valid element of an Objective-C
392 /// collection literal.
CheckObjCCollectionLiteralElement(Sema & S,Expr * Element,QualType T,bool ArrayLiteral=false)393 static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,
394                                                     QualType T,
395                                                     bool ArrayLiteral = false) {
396   // If the expression is type-dependent, there's nothing for us to do.
397   if (Element->isTypeDependent())
398     return Element;
399 
400   ExprResult Result = S.CheckPlaceholderExpr(Element);
401   if (Result.isInvalid())
402     return ExprError();
403   Element = Result.get();
404 
405   // In C++, check for an implicit conversion to an Objective-C object pointer
406   // type.
407   if (S.getLangOpts().CPlusPlus && Element->getType()->isRecordType()) {
408     InitializedEntity Entity
409       = InitializedEntity::InitializeParameter(S.Context, T,
410                                                /*Consumed=*/false);
411     InitializationKind Kind = InitializationKind::CreateCopy(
412         Element->getBeginLoc(), SourceLocation());
413     InitializationSequence Seq(S, Entity, Kind, Element);
414     if (!Seq.Failed())
415       return Seq.Perform(S, Entity, Kind, Element);
416   }
417 
418   Expr *OrigElement = Element;
419 
420   // Perform lvalue-to-rvalue conversion.
421   Result = S.DefaultLvalueConversion(Element);
422   if (Result.isInvalid())
423     return ExprError();
424   Element = Result.get();
425 
426   // Make sure that we have an Objective-C pointer type or block.
427   if (!Element->getType()->isObjCObjectPointerType() &&
428       !Element->getType()->isBlockPointerType()) {
429     bool Recovered = false;
430 
431     // If this is potentially an Objective-C numeric literal, add the '@'.
432     if (isa<IntegerLiteral>(OrigElement) ||
433         isa<CharacterLiteral>(OrigElement) ||
434         isa<FloatingLiteral>(OrigElement) ||
435         isa<ObjCBoolLiteralExpr>(OrigElement) ||
436         isa<CXXBoolLiteralExpr>(OrigElement)) {
437       if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(
438               OrigElement->getType())) {
439         int Which = isa<CharacterLiteral>(OrigElement) ? 1
440                   : (isa<CXXBoolLiteralExpr>(OrigElement) ||
441                      isa<ObjCBoolLiteralExpr>(OrigElement)) ? 2
442                   : 3;
443 
444         S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
445             << Which << OrigElement->getSourceRange()
446             << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");
447 
448         Result = S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(),
449                                                   OrigElement);
450         if (Result.isInvalid())
451           return ExprError();
452 
453         Element = Result.get();
454         Recovered = true;
455       }
456     }
457     // If this is potentially an Objective-C string literal, add the '@'.
458     else if (StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {
459       if (String->isOrdinary()) {
460         S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
461             << 0 << OrigElement->getSourceRange()
462             << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");
463 
464         Result =
465             S.ObjC().BuildObjCStringLiteral(OrigElement->getBeginLoc(), String);
466         if (Result.isInvalid())
467           return ExprError();
468 
469         Element = Result.get();
470         Recovered = true;
471       }
472     }
473 
474     if (!Recovered) {
475       S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)
476           << Element->getType();
477       return ExprError();
478     }
479   }
480   if (ArrayLiteral)
481     if (ObjCStringLiteral *getString =
482           dyn_cast<ObjCStringLiteral>(OrigElement)) {
483       if (StringLiteral *SL = getString->getString()) {
484         unsigned numConcat = SL->getNumConcatenated();
485         if (numConcat > 1) {
486           // Only warn if the concatenated string doesn't come from a macro.
487           bool hasMacro = false;
488           for (unsigned i = 0; i < numConcat ; ++i)
489             if (SL->getStrTokenLoc(i).isMacroID()) {
490               hasMacro = true;
491               break;
492             }
493           if (!hasMacro)
494             S.Diag(Element->getBeginLoc(),
495                    diag::warn_concatenated_nsarray_literal)
496                 << Element->getType();
497         }
498       }
499     }
500 
501   // Make sure that the element has the type that the container factory
502   // function expects.
503   return S.PerformCopyInitialization(
504       InitializedEntity::InitializeParameter(S.Context, T,
505                                              /*Consumed=*/false),
506       Element->getBeginLoc(), Element);
507 }
508 
BuildObjCBoxedExpr(SourceRange SR,Expr * ValueExpr)509 ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
510   ASTContext &Context = getASTContext();
511   if (ValueExpr->isTypeDependent()) {
512     ObjCBoxedExpr *BoxedExpr =
513       new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);
514     return BoxedExpr;
515   }
516   ObjCMethodDecl *BoxingMethod = nullptr;
517   QualType BoxedType;
518   // Convert the expression to an RValue, so we can check for pointer types...
519   ExprResult RValue = SemaRef.DefaultFunctionArrayLvalueConversion(ValueExpr);
520   if (RValue.isInvalid()) {
521     return ExprError();
522   }
523   SourceLocation Loc = SR.getBegin();
524   ValueExpr = RValue.get();
525   QualType ValueType(ValueExpr->getType());
526   if (const PointerType *PT = ValueType->getAs<PointerType>()) {
527     QualType PointeeType = PT->getPointeeType();
528     if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
529 
530       if (!NSStringDecl) {
531         NSStringDecl =
532             LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_String);
533         if (!NSStringDecl) {
534           return ExprError();
535         }
536         QualType NSStringObject = Context.getObjCInterfaceType(NSStringDecl);
537         NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);
538       }
539 
540       // The boxed expression can be emitted as a compile time constant if it is
541       // a string literal whose character encoding is compatible with UTF-8.
542       if (auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))
543         if (CE->getCastKind() == CK_ArrayToPointerDecay)
544           if (auto *SL =
545                   dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {
546             assert((SL->isOrdinary() || SL->isUTF8()) &&
547                    "unexpected character encoding");
548             StringRef Str = SL->getString();
549             const llvm::UTF8 *StrBegin = Str.bytes_begin();
550             const llvm::UTF8 *StrEnd = Str.bytes_end();
551             // Check that this is a valid UTF-8 string.
552             if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
553               BoxedType = Context.getAttributedType(
554                   AttributedType::getNullabilityAttrKind(
555                       NullabilityKind::NonNull),
556                   NSStringPointer, NSStringPointer);
557               return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);
558             }
559 
560             Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
561                 << NSStringPointer << SL->getSourceRange();
562           }
563 
564       if (!StringWithUTF8StringMethod) {
565         IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
566         Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
567 
568         // Look for the appropriate method within NSString.
569         BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
570         if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
571           // Debugger needs to work even if NSString hasn't been defined.
572           TypeSourceInfo *ReturnTInfo = nullptr;
573           ObjCMethodDecl *M = ObjCMethodDecl::Create(
574               Context, SourceLocation(), SourceLocation(), stringWithUTF8String,
575               NSStringPointer, ReturnTInfo, NSStringDecl,
576               /*isInstance=*/false, /*isVariadic=*/false,
577               /*isPropertyAccessor=*/false,
578               /*isSynthesizedAccessorStub=*/false,
579               /*isImplicitlyDeclared=*/true,
580               /*isDefined=*/false, ObjCImplementationControl::Required,
581               /*HasRelatedResultType=*/false);
582           QualType ConstCharType = Context.CharTy.withConst();
583           ParmVarDecl *value =
584             ParmVarDecl::Create(Context, M,
585                                 SourceLocation(), SourceLocation(),
586                                 &Context.Idents.get("value"),
587                                 Context.getPointerType(ConstCharType),
588                                 /*TInfo=*/nullptr,
589                                 SC_None, nullptr);
590           M->setMethodParams(Context, value, std::nullopt);
591           BoxingMethod = M;
592         }
593 
594         if (!validateBoxingMethod(SemaRef, Loc, NSStringDecl,
595                                   stringWithUTF8String, BoxingMethod))
596           return ExprError();
597 
598         StringWithUTF8StringMethod = BoxingMethod;
599       }
600 
601       BoxingMethod = StringWithUTF8StringMethod;
602       BoxedType = NSStringPointer;
603       // Transfer the nullability from method's return type.
604       std::optional<NullabilityKind> Nullability =
605           BoxingMethod->getReturnType()->getNullability();
606       if (Nullability)
607         BoxedType = Context.getAttributedType(
608             AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
609             BoxedType);
610     }
611   } else if (ValueType->isBuiltinType()) {
612     // The other types we support are numeric, char and BOOL/bool. We could also
613     // provide limited support for structure types, such as NSRange, NSRect, and
614     // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h>
615     // for more details.
616 
617     // Check for a top-level character literal.
618     if (const CharacterLiteral *Char =
619         dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {
620       // In C, character literals have type 'int'. That's not the type we want
621       // to use to determine the Objective-c literal kind.
622       switch (Char->getKind()) {
623       case CharacterLiteralKind::Ascii:
624       case CharacterLiteralKind::UTF8:
625         ValueType = Context.CharTy;
626         break;
627 
628       case CharacterLiteralKind::Wide:
629         ValueType = Context.getWideCharType();
630         break;
631 
632       case CharacterLiteralKind::UTF16:
633         ValueType = Context.Char16Ty;
634         break;
635 
636       case CharacterLiteralKind::UTF32:
637         ValueType = Context.Char32Ty;
638         break;
639       }
640     }
641     // FIXME:  Do I need to do anything special with BoolTy expressions?
642 
643     // Look for the appropriate method within NSNumber.
644     BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType);
645     BoxedType = NSNumberPointer;
646   } else if (const EnumType *ET = ValueType->getAs<EnumType>()) {
647     if (!ET->getDecl()->isComplete()) {
648       Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
649         << ValueType << ValueExpr->getSourceRange();
650       return ExprError();
651     }
652 
653     BoxingMethod = getNSNumberFactoryMethod(*this, Loc,
654                                             ET->getDecl()->getIntegerType());
655     BoxedType = NSNumberPointer;
656   } else if (ValueType->isObjCBoxableRecordType()) {
657     // Support for structure types, that marked as objc_boxable
658     // struct __attribute__((objc_boxable)) s { ... };
659 
660     // Look up the NSValue class, if we haven't done so already. It's cached
661     // in the Sema instance.
662     if (!NSValueDecl) {
663       NSValueDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_Boxed);
664       if (!NSValueDecl) {
665         return ExprError();
666       }
667 
668       // generate the pointer to NSValue type.
669       QualType NSValueObject = Context.getObjCInterfaceType(NSValueDecl);
670       NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);
671     }
672 
673     if (!ValueWithBytesObjCTypeMethod) {
674       const IdentifierInfo *II[] = {&Context.Idents.get("valueWithBytes"),
675                                     &Context.Idents.get("objCType")};
676       Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
677 
678       // Look for the appropriate method within NSValue.
679       BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
680       if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
681         // Debugger needs to work even if NSValue hasn't been defined.
682         TypeSourceInfo *ReturnTInfo = nullptr;
683         ObjCMethodDecl *M = ObjCMethodDecl::Create(
684             Context, SourceLocation(), SourceLocation(), ValueWithBytesObjCType,
685             NSValuePointer, ReturnTInfo, NSValueDecl,
686             /*isInstance=*/false,
687             /*isVariadic=*/false,
688             /*isPropertyAccessor=*/false,
689             /*isSynthesizedAccessorStub=*/false,
690             /*isImplicitlyDeclared=*/true,
691             /*isDefined=*/false, ObjCImplementationControl::Required,
692             /*HasRelatedResultType=*/false);
693 
694         SmallVector<ParmVarDecl *, 2> Params;
695 
696         ParmVarDecl *bytes =
697         ParmVarDecl::Create(Context, M,
698                             SourceLocation(), SourceLocation(),
699                             &Context.Idents.get("bytes"),
700                             Context.VoidPtrTy.withConst(),
701                             /*TInfo=*/nullptr,
702                             SC_None, nullptr);
703         Params.push_back(bytes);
704 
705         QualType ConstCharType = Context.CharTy.withConst();
706         ParmVarDecl *type =
707         ParmVarDecl::Create(Context, M,
708                             SourceLocation(), SourceLocation(),
709                             &Context.Idents.get("type"),
710                             Context.getPointerType(ConstCharType),
711                             /*TInfo=*/nullptr,
712                             SC_None, nullptr);
713         Params.push_back(type);
714 
715         M->setMethodParams(Context, Params, std::nullopt);
716         BoxingMethod = M;
717       }
718 
719       if (!validateBoxingMethod(SemaRef, Loc, NSValueDecl,
720                                 ValueWithBytesObjCType, BoxingMethod))
721         return ExprError();
722 
723       ValueWithBytesObjCTypeMethod = BoxingMethod;
724     }
725 
726     if (!ValueType.isTriviallyCopyableType(Context)) {
727       Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
728         << ValueType << ValueExpr->getSourceRange();
729       return ExprError();
730     }
731 
732     BoxingMethod = ValueWithBytesObjCTypeMethod;
733     BoxedType = NSValuePointer;
734   }
735 
736   if (!BoxingMethod) {
737     Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
738       << ValueType << ValueExpr->getSourceRange();
739     return ExprError();
740   }
741 
742   SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);
743 
744   ExprResult ConvertedValueExpr;
745   if (ValueType->isObjCBoxableRecordType()) {
746     InitializedEntity IE = InitializedEntity::InitializeTemporary(ValueType);
747     ConvertedValueExpr = SemaRef.PerformCopyInitialization(
748         IE, ValueExpr->getExprLoc(), ValueExpr);
749   } else {
750     // Convert the expression to the type that the parameter requires.
751     ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
752     InitializedEntity IE = InitializedEntity::InitializeParameter(Context,
753                                                                   ParamDecl);
754     ConvertedValueExpr =
755         SemaRef.PerformCopyInitialization(IE, SourceLocation(), ValueExpr);
756   }
757 
758   if (ConvertedValueExpr.isInvalid())
759     return ExprError();
760   ValueExpr = ConvertedValueExpr.get();
761 
762   ObjCBoxedExpr *BoxedExpr =
763     new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
764                                       BoxingMethod, SR);
765   return SemaRef.MaybeBindToTemporary(BoxedExpr);
766 }
767 
768 /// Build an ObjC subscript pseudo-object expression, given that
769 /// that's supported by the runtime.
BuildObjCSubscriptExpression(SourceLocation RB,Expr * BaseExpr,Expr * IndexExpr,ObjCMethodDecl * getterMethod,ObjCMethodDecl * setterMethod)770 ExprResult SemaObjC::BuildObjCSubscriptExpression(
771     SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr,
772     ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) {
773   assert(!getLangOpts().isSubscriptPointerArithmetic());
774   ASTContext &Context = getASTContext();
775 
776   // We can't get dependent types here; our callers should have
777   // filtered them out.
778   assert((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
779          "base or index cannot have dependent type here");
780 
781   // Filter out placeholders in the index.  In theory, overloads could
782   // be preserved here, although that might not actually work correctly.
783   ExprResult Result = SemaRef.CheckPlaceholderExpr(IndexExpr);
784   if (Result.isInvalid())
785     return ExprError();
786   IndexExpr = Result.get();
787 
788   // Perform lvalue-to-rvalue conversion on the base.
789   Result = SemaRef.DefaultLvalueConversion(BaseExpr);
790   if (Result.isInvalid())
791     return ExprError();
792   BaseExpr = Result.get();
793 
794   // Build the pseudo-object expression.
795   return new (Context) ObjCSubscriptRefExpr(
796       BaseExpr, IndexExpr, Context.PseudoObjectTy, VK_LValue, OK_ObjCSubscript,
797       getterMethod, setterMethod, RB);
798 }
799 
BuildObjCArrayLiteral(SourceRange SR,MultiExprArg Elements)800 ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR,
801                                            MultiExprArg Elements) {
802   ASTContext &Context = getASTContext();
803   SourceLocation Loc = SR.getBegin();
804 
805   if (!NSArrayDecl) {
806     NSArrayDecl =
807         LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, SemaObjC::LK_Array);
808     if (!NSArrayDecl) {
809       return ExprError();
810     }
811   }
812 
813   // Find the arrayWithObjects:count: method, if we haven't done so already.
814   QualType IdT = Context.getObjCIdType();
815   if (!ArrayWithObjectsMethod) {
816     Selector
817       Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
818     ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel);
819     if (!Method && getLangOpts().DebuggerObjCLiteral) {
820       TypeSourceInfo *ReturnTInfo = nullptr;
821       Method = ObjCMethodDecl::Create(
822           Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,
823           Context.getTranslationUnitDecl(), false /*Instance*/,
824           false /*isVariadic*/,
825           /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false,
826           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
827           ObjCImplementationControl::Required, false);
828       SmallVector<ParmVarDecl *, 2> Params;
829       ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
830                                                  SourceLocation(),
831                                                  SourceLocation(),
832                                                  &Context.Idents.get("objects"),
833                                                  Context.getPointerType(IdT),
834                                                  /*TInfo=*/nullptr,
835                                                  SC_None, nullptr);
836       Params.push_back(objects);
837       ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
838                                              SourceLocation(),
839                                              SourceLocation(),
840                                              &Context.Idents.get("cnt"),
841                                              Context.UnsignedLongTy,
842                                              /*TInfo=*/nullptr, SC_None,
843                                              nullptr);
844       Params.push_back(cnt);
845       Method->setMethodParams(Context, Params, std::nullopt);
846     }
847 
848     if (!validateBoxingMethod(SemaRef, Loc, NSArrayDecl, Sel, Method))
849       return ExprError();
850 
851     // Dig out the type that all elements should be converted to.
852     QualType T = Method->parameters()[0]->getType();
853     const PointerType *PtrT = T->getAs<PointerType>();
854     if (!PtrT ||
855         !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
856       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
857         << Sel;
858       Diag(Method->parameters()[0]->getLocation(),
859            diag::note_objc_literal_method_param)
860         << 0 << T
861         << Context.getPointerType(IdT.withConst());
862       return ExprError();
863     }
864 
865     // Check that the 'count' parameter is integral.
866     if (!Method->parameters()[1]->getType()->isIntegerType()) {
867       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
868         << Sel;
869       Diag(Method->parameters()[1]->getLocation(),
870            diag::note_objc_literal_method_param)
871         << 1
872         << Method->parameters()[1]->getType()
873         << "integral";
874       return ExprError();
875     }
876 
877     // We've found a good +arrayWithObjects:count: method. Save it!
878     ArrayWithObjectsMethod = Method;
879   }
880 
881   QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
882   QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
883 
884   // Check that each of the elements provided is valid in a collection literal,
885   // performing conversions as necessary.
886   Expr **ElementsBuffer = Elements.data();
887   for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
888     ExprResult Converted = CheckObjCCollectionLiteralElement(
889         SemaRef, ElementsBuffer[I], RequiredType, true);
890     if (Converted.isInvalid())
891       return ExprError();
892 
893     ElementsBuffer[I] = Converted.get();
894   }
895 
896   QualType Ty
897     = Context.getObjCObjectPointerType(
898                                     Context.getObjCInterfaceType(NSArrayDecl));
899 
900   return SemaRef.MaybeBindToTemporary(ObjCArrayLiteral::Create(
901       Context, Elements, Ty, ArrayWithObjectsMethod, SR));
902 }
903 
904 /// Check for duplicate keys in an ObjC dictionary literal. For instance:
905 ///   NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };
906 static void
CheckObjCDictionaryLiteralDuplicateKeys(Sema & S,ObjCDictionaryLiteral * Literal)907 CheckObjCDictionaryLiteralDuplicateKeys(Sema &S,
908                                         ObjCDictionaryLiteral *Literal) {
909   if (Literal->isValueDependent() || Literal->isTypeDependent())
910     return;
911 
912   // NSNumber has quite relaxed equality semantics (for instance, @YES is
913   // considered equal to @1.0). For now, ignore floating points and just do a
914   // bit-width and sign agnostic integer compare.
915   struct APSIntCompare {
916     bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {
917       return llvm::APSInt::compareValues(LHS, RHS) < 0;
918     }
919   };
920 
921   llvm::DenseMap<StringRef, SourceLocation> StringKeys;
922   std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
923 
924   auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {
925     auto Pair = Map.insert({Key, Loc});
926     if (!Pair.second) {
927       S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);
928       S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
929     }
930   };
931 
932   for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
933     Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
934 
935     if (auto *StrLit = dyn_cast<ObjCStringLiteral>(Key)) {
936       StringRef Bytes = StrLit->getString()->getBytes();
937       SourceLocation Loc = StrLit->getExprLoc();
938       checkOneKey(StringKeys, Bytes, Loc);
939     }
940 
941     if (auto *BE = dyn_cast<ObjCBoxedExpr>(Key)) {
942       Expr *Boxed = BE->getSubExpr();
943       SourceLocation Loc = BE->getExprLoc();
944 
945       // Check for @("foo").
946       if (auto *Str = dyn_cast<StringLiteral>(Boxed->IgnoreParenImpCasts())) {
947         checkOneKey(StringKeys, Str->getBytes(), Loc);
948         continue;
949       }
950 
951       Expr::EvalResult Result;
952       if (Boxed->EvaluateAsInt(Result, S.getASTContext(),
953                                Expr::SE_AllowSideEffects)) {
954         checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
955       }
956     }
957   }
958 }
959 
BuildObjCDictionaryLiteral(SourceRange SR,MutableArrayRef<ObjCDictionaryElement> Elements)960 ExprResult SemaObjC::BuildObjCDictionaryLiteral(
961     SourceRange SR, MutableArrayRef<ObjCDictionaryElement> Elements) {
962   ASTContext &Context = getASTContext();
963   SourceLocation Loc = SR.getBegin();
964 
965   if (!NSDictionaryDecl) {
966     NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral(
967         SemaRef, Loc, SemaObjC::LK_Dictionary);
968     if (!NSDictionaryDecl) {
969       return ExprError();
970     }
971   }
972 
973   // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
974   // so already.
975   QualType IdT = Context.getObjCIdType();
976   if (!DictionaryWithObjectsMethod) {
977     Selector Sel = NSAPIObj->getNSDictionarySelector(
978                                NSAPI::NSDict_dictionaryWithObjectsForKeysCount);
979     ObjCMethodDecl *Method = NSDictionaryDecl->lookupClassMethod(Sel);
980     if (!Method && getLangOpts().DebuggerObjCLiteral) {
981       Method = ObjCMethodDecl::Create(
982           Context, SourceLocation(), SourceLocation(), Sel, IdT,
983           nullptr /*TypeSourceInfo */, Context.getTranslationUnitDecl(),
984           false /*Instance*/, false /*isVariadic*/,
985           /*isPropertyAccessor=*/false,
986           /*isSynthesizedAccessorStub=*/false,
987           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
988           ObjCImplementationControl::Required, false);
989       SmallVector<ParmVarDecl *, 3> Params;
990       ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
991                                                  SourceLocation(),
992                                                  SourceLocation(),
993                                                  &Context.Idents.get("objects"),
994                                                  Context.getPointerType(IdT),
995                                                  /*TInfo=*/nullptr, SC_None,
996                                                  nullptr);
997       Params.push_back(objects);
998       ParmVarDecl *keys = ParmVarDecl::Create(Context, Method,
999                                               SourceLocation(),
1000                                               SourceLocation(),
1001                                               &Context.Idents.get("keys"),
1002                                               Context.getPointerType(IdT),
1003                                               /*TInfo=*/nullptr, SC_None,
1004                                               nullptr);
1005       Params.push_back(keys);
1006       ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
1007                                              SourceLocation(),
1008                                              SourceLocation(),
1009                                              &Context.Idents.get("cnt"),
1010                                              Context.UnsignedLongTy,
1011                                              /*TInfo=*/nullptr, SC_None,
1012                                              nullptr);
1013       Params.push_back(cnt);
1014       Method->setMethodParams(Context, Params, std::nullopt);
1015     }
1016 
1017     if (!validateBoxingMethod(SemaRef, SR.getBegin(), NSDictionaryDecl, Sel,
1018                               Method))
1019       return ExprError();
1020 
1021     // Dig out the type that all values should be converted to.
1022     QualType ValueT = Method->parameters()[0]->getType();
1023     const PointerType *PtrValue = ValueT->getAs<PointerType>();
1024     if (!PtrValue ||
1025         !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
1026       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1027         << Sel;
1028       Diag(Method->parameters()[0]->getLocation(),
1029            diag::note_objc_literal_method_param)
1030         << 0 << ValueT
1031         << Context.getPointerType(IdT.withConst());
1032       return ExprError();
1033     }
1034 
1035     // Dig out the type that all keys should be converted to.
1036     QualType KeyT = Method->parameters()[1]->getType();
1037     const PointerType *PtrKey = KeyT->getAs<PointerType>();
1038     if (!PtrKey ||
1039         !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1040                                         IdT)) {
1041       bool err = true;
1042       if (PtrKey) {
1043         if (QIDNSCopying.isNull()) {
1044           // key argument of selector is id<NSCopying>?
1045           if (ObjCProtocolDecl *NSCopyingPDecl =
1046               LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {
1047             ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};
1048             QIDNSCopying = Context.getObjCObjectType(
1049                 Context.ObjCBuiltinIdTy, {},
1050                 llvm::ArrayRef((ObjCProtocolDecl **)PQ, 1), false);
1051             QIDNSCopying = Context.getObjCObjectPointerType(QIDNSCopying);
1052           }
1053         }
1054         if (!QIDNSCopying.isNull())
1055           err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1056                                                 QIDNSCopying);
1057       }
1058 
1059       if (err) {
1060         Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1061           << Sel;
1062         Diag(Method->parameters()[1]->getLocation(),
1063              diag::note_objc_literal_method_param)
1064           << 1 << KeyT
1065           << Context.getPointerType(IdT.withConst());
1066         return ExprError();
1067       }
1068     }
1069 
1070     // Check that the 'count' parameter is integral.
1071     QualType CountType = Method->parameters()[2]->getType();
1072     if (!CountType->isIntegerType()) {
1073       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1074         << Sel;
1075       Diag(Method->parameters()[2]->getLocation(),
1076            diag::note_objc_literal_method_param)
1077         << 2 << CountType
1078         << "integral";
1079       return ExprError();
1080     }
1081 
1082     // We've found a good +dictionaryWithObjects:keys:count: method; save it!
1083     DictionaryWithObjectsMethod = Method;
1084   }
1085 
1086   QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
1087   QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
1088   QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
1089   QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
1090 
1091   // Check that each of the keys and values provided is valid in a collection
1092   // literal, performing conversions as necessary.
1093   bool HasPackExpansions = false;
1094   for (ObjCDictionaryElement &Element : Elements) {
1095     // Check the key.
1096     ExprResult Key =
1097         CheckObjCCollectionLiteralElement(SemaRef, Element.Key, KeyT);
1098     if (Key.isInvalid())
1099       return ExprError();
1100 
1101     // Check the value.
1102     ExprResult Value =
1103         CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT);
1104     if (Value.isInvalid())
1105       return ExprError();
1106 
1107     Element.Key = Key.get();
1108     Element.Value = Value.get();
1109 
1110     if (Element.EllipsisLoc.isInvalid())
1111       continue;
1112 
1113     if (!Element.Key->containsUnexpandedParameterPack() &&
1114         !Element.Value->containsUnexpandedParameterPack()) {
1115       Diag(Element.EllipsisLoc,
1116            diag::err_pack_expansion_without_parameter_packs)
1117           << SourceRange(Element.Key->getBeginLoc(),
1118                          Element.Value->getEndLoc());
1119       return ExprError();
1120     }
1121 
1122     HasPackExpansions = true;
1123   }
1124 
1125   QualType Ty = Context.getObjCObjectPointerType(
1126       Context.getObjCInterfaceType(NSDictionaryDecl));
1127 
1128   auto *Literal =
1129       ObjCDictionaryLiteral::Create(Context, Elements, HasPackExpansions, Ty,
1130                                     DictionaryWithObjectsMethod, SR);
1131   CheckObjCDictionaryLiteralDuplicateKeys(SemaRef, Literal);
1132   return SemaRef.MaybeBindToTemporary(Literal);
1133 }
1134 
BuildObjCEncodeExpression(SourceLocation AtLoc,TypeSourceInfo * EncodedTypeInfo,SourceLocation RParenLoc)1135 ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc,
1136                                                TypeSourceInfo *EncodedTypeInfo,
1137                                                SourceLocation RParenLoc) {
1138   ASTContext &Context = getASTContext();
1139   QualType EncodedType = EncodedTypeInfo->getType();
1140   QualType StrTy;
1141   if (EncodedType->isDependentType())
1142     StrTy = Context.DependentTy;
1143   else {
1144     if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
1145         !EncodedType->isVoidType()) // void is handled too.
1146       if (SemaRef.RequireCompleteType(AtLoc, EncodedType,
1147                                       diag::err_incomplete_type_objc_at_encode,
1148                                       EncodedTypeInfo->getTypeLoc()))
1149         return ExprError();
1150 
1151     std::string Str;
1152     QualType NotEncodedT;
1153     Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);
1154     if (!NotEncodedT.isNull())
1155       Diag(AtLoc, diag::warn_incomplete_encoded_type)
1156         << EncodedType << NotEncodedT;
1157 
1158     // The type of @encode is the same as the type of the corresponding string,
1159     // which is an array type.
1160     StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1161   }
1162 
1163   return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1164 }
1165 
ParseObjCEncodeExpression(SourceLocation AtLoc,SourceLocation EncodeLoc,SourceLocation LParenLoc,ParsedType ty,SourceLocation RParenLoc)1166 ExprResult SemaObjC::ParseObjCEncodeExpression(SourceLocation AtLoc,
1167                                                SourceLocation EncodeLoc,
1168                                                SourceLocation LParenLoc,
1169                                                ParsedType ty,
1170                                                SourceLocation RParenLoc) {
1171   ASTContext &Context = getASTContext();
1172   // FIXME: Preserve type source info ?
1173   TypeSourceInfo *TInfo;
1174   QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo);
1175   if (!TInfo)
1176     TInfo = Context.getTrivialTypeSourceInfo(
1177         EncodedType, SemaRef.getLocForEndOfToken(LParenLoc));
1178 
1179   return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
1180 }
1181 
HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema & S,SourceLocation AtLoc,SourceLocation LParenLoc,SourceLocation RParenLoc,ObjCMethodDecl * Method,ObjCMethodList & MethList)1182 static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
1183                                                SourceLocation AtLoc,
1184                                                SourceLocation LParenLoc,
1185                                                SourceLocation RParenLoc,
1186                                                ObjCMethodDecl *Method,
1187                                                ObjCMethodList &MethList) {
1188   ObjCMethodList *M = &MethList;
1189   bool Warned = false;
1190   for (M = M->getNext(); M; M=M->getNext()) {
1191     ObjCMethodDecl *MatchingMethodDecl = M->getMethod();
1192     if (MatchingMethodDecl == Method ||
1193         isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||
1194         MatchingMethodDecl->getSelector() != Method->getSelector())
1195       continue;
1196     if (!S.ObjC().MatchTwoMethodDeclarations(Method, MatchingMethodDecl,
1197                                              SemaObjC::MMS_loose)) {
1198       if (!Warned) {
1199         Warned = true;
1200         S.Diag(AtLoc, diag::warn_multiple_selectors)
1201           << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
1202           << FixItHint::CreateInsertion(RParenLoc, ")");
1203         S.Diag(Method->getLocation(), diag::note_method_declared_at)
1204           << Method->getDeclName();
1205       }
1206       S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
1207         << MatchingMethodDecl->getDeclName();
1208     }
1209   }
1210   return Warned;
1211 }
1212 
DiagnoseMismatchedSelectors(Sema & S,SourceLocation AtLoc,ObjCMethodDecl * Method,SourceLocation LParenLoc,SourceLocation RParenLoc,bool WarnMultipleSelectors)1213 static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
1214                                         ObjCMethodDecl *Method,
1215                                         SourceLocation LParenLoc,
1216                                         SourceLocation RParenLoc,
1217                                         bool WarnMultipleSelectors) {
1218   if (!WarnMultipleSelectors ||
1219       S.Diags.isIgnored(diag::warn_multiple_selectors, SourceLocation()))
1220     return;
1221   bool Warned = false;
1222   for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(),
1223                                             e = S.ObjC().MethodPool.end();
1224        b != e; b++) {
1225     // first, instance methods
1226     ObjCMethodList &InstMethList = b->second.first;
1227     if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1228                                                       Method, InstMethList))
1229       Warned = true;
1230 
1231     // second, class methods
1232     ObjCMethodList &ClsMethList = b->second.second;
1233     if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1234                                                       Method, ClsMethList) || Warned)
1235       return;
1236   }
1237 }
1238 
LookupDirectMethodInMethodList(Sema & S,Selector Sel,ObjCMethodList & MethList,bool & onlyDirect,bool & anyDirect)1239 static ObjCMethodDecl *LookupDirectMethodInMethodList(Sema &S, Selector Sel,
1240                                                       ObjCMethodList &MethList,
1241                                                       bool &onlyDirect,
1242                                                       bool &anyDirect) {
1243   (void)Sel;
1244   ObjCMethodList *M = &MethList;
1245   ObjCMethodDecl *DirectMethod = nullptr;
1246   for (; M; M = M->getNext()) {
1247     ObjCMethodDecl *Method = M->getMethod();
1248     if (!Method)
1249       continue;
1250     assert(Method->getSelector() == Sel && "Method with wrong selector in method list");
1251     if (Method->isDirectMethod()) {
1252       anyDirect = true;
1253       DirectMethod = Method;
1254     } else
1255       onlyDirect = false;
1256   }
1257 
1258   return DirectMethod;
1259 }
1260 
1261 // Search the global pool for (potentially) direct methods matching the given
1262 // selector. If a non-direct method is found, set \param onlyDirect to false. If
1263 // a direct method is found, set \param anyDirect to true. Returns a direct
1264 // method, if any.
LookupDirectMethodInGlobalPool(Sema & S,Selector Sel,bool & onlyDirect,bool & anyDirect)1265 static ObjCMethodDecl *LookupDirectMethodInGlobalPool(Sema &S, Selector Sel,
1266                                                       bool &onlyDirect,
1267                                                       bool &anyDirect) {
1268   auto Iter = S.ObjC().MethodPool.find(Sel);
1269   if (Iter == S.ObjC().MethodPool.end())
1270     return nullptr;
1271 
1272   ObjCMethodDecl *DirectInstance = LookupDirectMethodInMethodList(
1273       S, Sel, Iter->second.first, onlyDirect, anyDirect);
1274   ObjCMethodDecl *DirectClass = LookupDirectMethodInMethodList(
1275       S, Sel, Iter->second.second, onlyDirect, anyDirect);
1276 
1277   return DirectInstance ? DirectInstance : DirectClass;
1278 }
1279 
findMethodInCurrentClass(Sema & S,Selector Sel)1280 static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) {
1281   auto *CurMD = S.getCurMethodDecl();
1282   if (!CurMD)
1283     return nullptr;
1284   ObjCInterfaceDecl *IFace = CurMD->getClassInterface();
1285 
1286   // The language enforce that only one direct method is present in a given
1287   // class, so we just need to find one method in the current class to know
1288   // whether Sel is potentially direct in this context.
1289   if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true))
1290     return MD;
1291   if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/true))
1292     return MD;
1293   if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false))
1294     return MD;
1295   if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/false))
1296     return MD;
1297 
1298   return nullptr;
1299 }
1300 
ParseObjCSelectorExpression(Selector Sel,SourceLocation AtLoc,SourceLocation SelLoc,SourceLocation LParenLoc,SourceLocation RParenLoc,bool WarnMultipleSelectors)1301 ExprResult SemaObjC::ParseObjCSelectorExpression(Selector Sel,
1302                                                  SourceLocation AtLoc,
1303                                                  SourceLocation SelLoc,
1304                                                  SourceLocation LParenLoc,
1305                                                  SourceLocation RParenLoc,
1306                                                  bool WarnMultipleSelectors) {
1307   ASTContext &Context = getASTContext();
1308   ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
1309                              SourceRange(LParenLoc, RParenLoc));
1310   if (!Method)
1311     Method = LookupFactoryMethodInGlobalPool(Sel,
1312                                           SourceRange(LParenLoc, RParenLoc));
1313   if (!Method) {
1314     if (const ObjCMethodDecl *OM = SelectorsForTypoCorrection(Sel)) {
1315       Selector MatchedSel = OM->getSelector();
1316       SourceRange SelectorRange(LParenLoc.getLocWithOffset(1),
1317                                 RParenLoc.getLocWithOffset(-1));
1318       Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1319         << Sel << MatchedSel
1320         << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1321 
1322     } else
1323         Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1324   } else {
1325     DiagnoseMismatchedSelectors(SemaRef, AtLoc, Method, LParenLoc, RParenLoc,
1326                                 WarnMultipleSelectors);
1327 
1328     bool onlyDirect = true;
1329     bool anyDirect = false;
1330     ObjCMethodDecl *GlobalDirectMethod =
1331         LookupDirectMethodInGlobalPool(SemaRef, Sel, onlyDirect, anyDirect);
1332 
1333     if (onlyDirect) {
1334       Diag(AtLoc, diag::err_direct_selector_expression)
1335           << Method->getSelector();
1336       Diag(Method->getLocation(), diag::note_direct_method_declared_at)
1337           << Method->getDeclName();
1338     } else if (anyDirect) {
1339       // If we saw any direct methods, see if we see a direct member of the
1340       // current class. If so, the @selector will likely be used to refer to
1341       // this direct method.
1342       ObjCMethodDecl *LikelyTargetMethod =
1343           findMethodInCurrentClass(SemaRef, Sel);
1344       if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {
1345         Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1346         Diag(LikelyTargetMethod->getLocation(),
1347              diag::note_direct_method_declared_at)
1348             << LikelyTargetMethod->getDeclName();
1349       } else if (!LikelyTargetMethod) {
1350         // Otherwise, emit the "strict" variant of this diagnostic, unless
1351         // LikelyTargetMethod is non-direct.
1352         Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1353             << Sel;
1354         Diag(GlobalDirectMethod->getLocation(),
1355              diag::note_direct_method_declared_at)
1356             << GlobalDirectMethod->getDeclName();
1357       }
1358     }
1359   }
1360 
1361   if (Method &&
1362       Method->getImplementationControl() !=
1363           ObjCImplementationControl::Optional &&
1364       !SemaRef.getSourceManager().isInSystemHeader(Method->getLocation()))
1365     ReferencedSelectors.insert(std::make_pair(Sel, AtLoc));
1366 
1367   // In ARC, forbid the user from using @selector for
1368   // retain/release/autorelease/dealloc/retainCount.
1369   if (getLangOpts().ObjCAutoRefCount) {
1370     switch (Sel.getMethodFamily()) {
1371     case OMF_retain:
1372     case OMF_release:
1373     case OMF_autorelease:
1374     case OMF_retainCount:
1375     case OMF_dealloc:
1376       Diag(AtLoc, diag::err_arc_illegal_selector) <<
1377         Sel << SourceRange(LParenLoc, RParenLoc);
1378       break;
1379 
1380     case OMF_None:
1381     case OMF_alloc:
1382     case OMF_copy:
1383     case OMF_finalize:
1384     case OMF_init:
1385     case OMF_mutableCopy:
1386     case OMF_new:
1387     case OMF_self:
1388     case OMF_initialize:
1389     case OMF_performSelector:
1390       break;
1391     }
1392   }
1393   QualType Ty = Context.getObjCSelType();
1394   return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
1395 }
1396 
ParseObjCProtocolExpression(IdentifierInfo * ProtocolId,SourceLocation AtLoc,SourceLocation ProtoLoc,SourceLocation LParenLoc,SourceLocation ProtoIdLoc,SourceLocation RParenLoc)1397 ExprResult SemaObjC::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
1398                                                  SourceLocation AtLoc,
1399                                                  SourceLocation ProtoLoc,
1400                                                  SourceLocation LParenLoc,
1401                                                  SourceLocation ProtoIdLoc,
1402                                                  SourceLocation RParenLoc) {
1403   ASTContext &Context = getASTContext();
1404   ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc);
1405   if (!PDecl) {
1406     Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1407     return true;
1408   }
1409   if (PDecl->isNonRuntimeProtocol())
1410     Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1411         << PDecl;
1412   if (!PDecl->hasDefinition()) {
1413     Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1414     Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
1415   } else {
1416     PDecl = PDecl->getDefinition();
1417   }
1418 
1419   QualType Ty = Context.getObjCProtoType();
1420   if (Ty.isNull())
1421     return true;
1422   Ty = Context.getObjCObjectPointerType(Ty);
1423   return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1424 }
1425 
1426 /// Try to capture an implicit reference to 'self'.
tryCaptureObjCSelf(SourceLocation Loc)1427 ObjCMethodDecl *SemaObjC::tryCaptureObjCSelf(SourceLocation Loc) {
1428   DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
1429 
1430   // If we're not in an ObjC method, error out.  Note that, unlike the
1431   // C++ case, we don't require an instance method --- class methods
1432   // still have a 'self', and we really do still need to capture it!
1433   ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
1434   if (!method)
1435     return nullptr;
1436 
1437   SemaRef.tryCaptureVariable(method->getSelfDecl(), Loc);
1438 
1439   return method;
1440 }
1441 
stripObjCInstanceType(ASTContext & Context,QualType T)1442 static QualType stripObjCInstanceType(ASTContext &Context, QualType T) {
1443   QualType origType = T;
1444   if (auto nullability = AttributedType::stripOuterNullability(T)) {
1445     if (T == Context.getObjCInstanceType()) {
1446       return Context.getAttributedType(
1447                AttributedType::getNullabilityAttrKind(*nullability),
1448                Context.getObjCIdType(),
1449                Context.getObjCIdType());
1450     }
1451 
1452     return origType;
1453   }
1454 
1455   if (T == Context.getObjCInstanceType())
1456     return Context.getObjCIdType();
1457 
1458   return origType;
1459 }
1460 
1461 /// Determine the result type of a message send based on the receiver type,
1462 /// method, and the kind of message send.
1463 ///
1464 /// This is the "base" result type, which will still need to be adjusted
1465 /// to account for nullability.
getBaseMessageSendResultType(Sema & S,QualType ReceiverType,ObjCMethodDecl * Method,bool isClassMessage,bool isSuperMessage)1466 static QualType getBaseMessageSendResultType(Sema &S,
1467                                              QualType ReceiverType,
1468                                              ObjCMethodDecl *Method,
1469                                              bool isClassMessage,
1470                                              bool isSuperMessage) {
1471   assert(Method && "Must have a method");
1472   if (!Method->hasRelatedResultType())
1473     return Method->getSendResultType(ReceiverType);
1474 
1475   ASTContext &Context = S.Context;
1476 
1477   // Local function that transfers the nullability of the method's
1478   // result type to the returned result.
1479   auto transferNullability = [&](QualType type) -> QualType {
1480     // If the method's result type has nullability, extract it.
1481     if (auto nullability =
1482             Method->getSendResultType(ReceiverType)->getNullability()) {
1483       // Strip off any outer nullability sugar from the provided type.
1484       (void)AttributedType::stripOuterNullability(type);
1485 
1486       // Form a new attributed type using the method result type's nullability.
1487       return Context.getAttributedType(
1488                AttributedType::getNullabilityAttrKind(*nullability),
1489                type,
1490                type);
1491     }
1492 
1493     return type;
1494   };
1495 
1496   // If a method has a related return type:
1497   //   - if the method found is an instance method, but the message send
1498   //     was a class message send, T is the declared return type of the method
1499   //     found
1500   if (Method->isInstanceMethod() && isClassMessage)
1501     return stripObjCInstanceType(Context,
1502                                  Method->getSendResultType(ReceiverType));
1503 
1504   //   - if the receiver is super, T is a pointer to the class of the
1505   //     enclosing method definition
1506   if (isSuperMessage) {
1507     if (ObjCMethodDecl *CurMethod = S.getCurMethodDecl())
1508       if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {
1509         return transferNullability(
1510                  Context.getObjCObjectPointerType(
1511                    Context.getObjCInterfaceType(Class)));
1512       }
1513   }
1514 
1515   //   - if the receiver is the name of a class U, T is a pointer to U
1516   if (ReceiverType->getAsObjCInterfaceType())
1517     return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1518   //   - if the receiver is of type Class or qualified Class type,
1519   //     T is the declared return type of the method.
1520   if (ReceiverType->isObjCClassType() ||
1521       ReceiverType->isObjCQualifiedClassType())
1522     return stripObjCInstanceType(Context,
1523                                  Method->getSendResultType(ReceiverType));
1524 
1525   //   - if the receiver is id, qualified id, Class, or qualified Class, T
1526   //     is the receiver type, otherwise
1527   //   - T is the type of the receiver expression.
1528   return transferNullability(ReceiverType);
1529 }
1530 
getMessageSendResultType(const Expr * Receiver,QualType ReceiverType,ObjCMethodDecl * Method,bool isClassMessage,bool isSuperMessage)1531 QualType SemaObjC::getMessageSendResultType(const Expr *Receiver,
1532                                             QualType ReceiverType,
1533                                             ObjCMethodDecl *Method,
1534                                             bool isClassMessage,
1535                                             bool isSuperMessage) {
1536   ASTContext &Context = getASTContext();
1537   // Produce the result type.
1538   QualType resultType = getBaseMessageSendResultType(
1539       SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage);
1540 
1541   // If this is a class message, ignore the nullability of the receiver.
1542   if (isClassMessage) {
1543     // In a class method, class messages to 'self' that return instancetype can
1544     // be typed as the current class.  We can safely do this in ARC because self
1545     // can't be reassigned, and we do it unsafely outside of ARC because in
1546     // practice people never reassign self in class methods and there's some
1547     // virtue in not being aggressively pedantic.
1548     if (Receiver && Receiver->isObjCSelfExpr()) {
1549       assert(ReceiverType->isObjCClassType() && "expected a Class self");
1550       QualType T = Method->getSendResultType(ReceiverType);
1551       AttributedType::stripOuterNullability(T);
1552       if (T == Context.getObjCInstanceType()) {
1553         const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(
1554             cast<ImplicitParamDecl>(
1555                 cast<DeclRefExpr>(Receiver->IgnoreParenImpCasts())->getDecl())
1556                 ->getDeclContext());
1557         assert(MD->isClassMethod() && "expected a class method");
1558         QualType NewResultType = Context.getObjCObjectPointerType(
1559             Context.getObjCInterfaceType(MD->getClassInterface()));
1560         if (auto Nullability = resultType->getNullability())
1561           NewResultType = Context.getAttributedType(
1562               AttributedType::getNullabilityAttrKind(*Nullability),
1563               NewResultType, NewResultType);
1564         return NewResultType;
1565       }
1566     }
1567     return resultType;
1568   }
1569 
1570   // There is nothing left to do if the result type cannot have a nullability
1571   // specifier.
1572   if (!resultType->canHaveNullability())
1573     return resultType;
1574 
1575   // Map the nullability of the result into a table index.
1576   unsigned receiverNullabilityIdx = 0;
1577   if (std::optional<NullabilityKind> nullability =
1578           ReceiverType->getNullability()) {
1579     if (*nullability == NullabilityKind::NullableResult)
1580       nullability = NullabilityKind::Nullable;
1581     receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1582   }
1583 
1584   unsigned resultNullabilityIdx = 0;
1585   if (std::optional<NullabilityKind> nullability =
1586           resultType->getNullability()) {
1587     if (*nullability == NullabilityKind::NullableResult)
1588       nullability = NullabilityKind::Nullable;
1589     resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1590   }
1591 
1592   // The table of nullability mappings, indexed by the receiver's nullability
1593   // and then the result type's nullability.
1594   static const uint8_t None = 0;
1595   static const uint8_t NonNull = 1;
1596   static const uint8_t Nullable = 2;
1597   static const uint8_t Unspecified = 3;
1598   static const uint8_t nullabilityMap[4][4] = {
1599     //                  None        NonNull       Nullable    Unspecified
1600     /* None */        { None,       None,         Nullable,   None },
1601     /* NonNull */     { None,       NonNull,      Nullable,   Unspecified },
1602     /* Nullable */    { Nullable,   Nullable,     Nullable,   Nullable },
1603     /* Unspecified */ { None,       Unspecified,  Nullable,   Unspecified }
1604   };
1605 
1606   unsigned newResultNullabilityIdx
1607     = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1608   if (newResultNullabilityIdx == resultNullabilityIdx)
1609     return resultType;
1610 
1611   // Strip off the existing nullability. This removes as little type sugar as
1612   // possible.
1613   do {
1614     if (auto attributed = dyn_cast<AttributedType>(resultType.getTypePtr())) {
1615       resultType = attributed->getModifiedType();
1616     } else {
1617       resultType = resultType.getDesugaredType(Context);
1618     }
1619   } while (resultType->getNullability());
1620 
1621   // Add nullability back if needed.
1622   if (newResultNullabilityIdx > 0) {
1623     auto newNullability
1624       = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
1625     return Context.getAttributedType(
1626              AttributedType::getNullabilityAttrKind(newNullability),
1627              resultType, resultType);
1628   }
1629 
1630   return resultType;
1631 }
1632 
1633 /// Look for an ObjC method whose result type exactly matches the given type.
1634 static const ObjCMethodDecl *
findExplicitInstancetypeDeclarer(const ObjCMethodDecl * MD,QualType instancetype)1635 findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD,
1636                                  QualType instancetype) {
1637   if (MD->getReturnType() == instancetype)
1638     return MD;
1639 
1640   // For these purposes, a method in an @implementation overrides a
1641   // declaration in the @interface.
1642   if (const ObjCImplDecl *impl =
1643         dyn_cast<ObjCImplDecl>(MD->getDeclContext())) {
1644     const ObjCContainerDecl *iface;
1645     if (const ObjCCategoryImplDecl *catImpl =
1646           dyn_cast<ObjCCategoryImplDecl>(impl)) {
1647       iface = catImpl->getCategoryDecl();
1648     } else {
1649       iface = impl->getClassInterface();
1650     }
1651 
1652     const ObjCMethodDecl *ifaceMD =
1653       iface->getMethod(MD->getSelector(), MD->isInstanceMethod());
1654     if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype);
1655   }
1656 
1657   SmallVector<const ObjCMethodDecl *, 4> overrides;
1658   MD->getOverriddenMethods(overrides);
1659   for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
1660     if (const ObjCMethodDecl *result =
1661           findExplicitInstancetypeDeclarer(overrides[i], instancetype))
1662       return result;
1663   }
1664 
1665   return nullptr;
1666 }
1667 
EmitRelatedResultTypeNoteForReturn(QualType destType)1668 void SemaObjC::EmitRelatedResultTypeNoteForReturn(QualType destType) {
1669   ASTContext &Context = getASTContext();
1670   // Only complain if we're in an ObjC method and the required return
1671   // type doesn't match the method's declared return type.
1672   ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext);
1673   if (!MD || !MD->hasRelatedResultType() ||
1674       Context.hasSameUnqualifiedType(destType, MD->getReturnType()))
1675     return;
1676 
1677   // Look for a method overridden by this method which explicitly uses
1678   // 'instancetype'.
1679   if (const ObjCMethodDecl *overridden =
1680         findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) {
1681     SourceRange range = overridden->getReturnTypeSourceRange();
1682     SourceLocation loc = range.getBegin();
1683     if (loc.isInvalid())
1684       loc = overridden->getLocation();
1685     Diag(loc, diag::note_related_result_type_explicit)
1686       << /*current method*/ 1 << range;
1687     return;
1688   }
1689 
1690   // Otherwise, if we have an interesting method family, note that.
1691   // This should always trigger if the above didn't.
1692   if (ObjCMethodFamily family = MD->getMethodFamily())
1693     Diag(MD->getLocation(), diag::note_related_result_type_family)
1694       << /*current method*/ 1
1695       << family;
1696 }
1697 
EmitRelatedResultTypeNote(const Expr * E)1698 void SemaObjC::EmitRelatedResultTypeNote(const Expr *E) {
1699   ASTContext &Context = getASTContext();
1700   E = E->IgnoreParenImpCasts();
1701   const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
1702   if (!MsgSend)
1703     return;
1704 
1705   const ObjCMethodDecl *Method = MsgSend->getMethodDecl();
1706   if (!Method)
1707     return;
1708 
1709   if (!Method->hasRelatedResultType())
1710     return;
1711 
1712   if (Context.hasSameUnqualifiedType(
1713           Method->getReturnType().getNonReferenceType(), MsgSend->getType()))
1714     return;
1715 
1716   if (!Context.hasSameUnqualifiedType(Method->getReturnType(),
1717                                       Context.getObjCInstanceType()))
1718     return;
1719 
1720   Diag(Method->getLocation(), diag::note_related_result_type_inferred)
1721     << Method->isInstanceMethod() << Method->getSelector()
1722     << MsgSend->getType();
1723 }
1724 
CheckMessageArgumentTypes(const Expr * Receiver,QualType ReceiverType,MultiExprArg Args,Selector Sel,ArrayRef<SourceLocation> SelectorLocs,ObjCMethodDecl * Method,bool isClassMessage,bool isSuperMessage,SourceLocation lbrac,SourceLocation rbrac,SourceRange RecRange,QualType & ReturnType,ExprValueKind & VK)1725 bool SemaObjC::CheckMessageArgumentTypes(
1726     const Expr *Receiver, QualType ReceiverType, MultiExprArg Args,
1727     Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method,
1728     bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
1729     SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType,
1730     ExprValueKind &VK) {
1731   ASTContext &Context = getASTContext();
1732   SourceLocation SelLoc;
1733   if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1734     SelLoc = SelectorLocs.front();
1735   else
1736     SelLoc = lbrac;
1737 
1738   if (!Method) {
1739     // Apply default argument promotion as for (C99 6.5.2.2p6).
1740     for (unsigned i = 0, e = Args.size(); i != e; i++) {
1741       if (Args[i]->isTypeDependent())
1742         continue;
1743 
1744       ExprResult result;
1745       if (getLangOpts().DebuggerSupport) {
1746         QualType paramTy; // ignored
1747         result = SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1748       } else {
1749         result = SemaRef.DefaultArgumentPromotion(Args[i]);
1750       }
1751       if (result.isInvalid())
1752         return true;
1753       Args[i] = result.get();
1754     }
1755 
1756     unsigned DiagID;
1757     if (getLangOpts().ObjCAutoRefCount)
1758       DiagID = diag::err_arc_method_not_found;
1759     else
1760       DiagID = isClassMessage ? diag::warn_class_method_not_found
1761                               : diag::warn_inst_method_not_found;
1762     if (!getLangOpts().DebuggerSupport) {
1763       const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);
1764       if (OMD && !OMD->isInvalidDecl()) {
1765         if (getLangOpts().ObjCAutoRefCount)
1766           DiagID = diag::err_method_not_found_with_typo;
1767         else
1768           DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1769                                   : diag::warn_instance_method_not_found_with_typo;
1770         Selector MatchedSel = OMD->getSelector();
1771         SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1772         if (MatchedSel.isUnarySelector())
1773           Diag(SelLoc, DiagID)
1774             << Sel<< isClassMessage << MatchedSel
1775             << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1776         else
1777           Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1778       }
1779       else
1780         Diag(SelLoc, DiagID)
1781           << Sel << isClassMessage << SourceRange(SelectorLocs.front(),
1782                                                 SelectorLocs.back());
1783       // Find the class to which we are sending this message.
1784       if (auto *ObjPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
1785         if (ObjCInterfaceDecl *ThisClass = ObjPT->getInterfaceDecl()) {
1786           Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1787           if (!RecRange.isInvalid())
1788             if (ThisClass->lookupClassMethod(Sel))
1789               Diag(RecRange.getBegin(), diag::note_receiver_expr_here)
1790                   << FixItHint::CreateReplacement(RecRange,
1791                                                   ThisClass->getNameAsString());
1792         }
1793       }
1794     }
1795 
1796     // In debuggers, we want to use __unknown_anytype for these
1797     // results so that clients can cast them.
1798     if (getLangOpts().DebuggerSupport) {
1799       ReturnType = Context.UnknownAnyTy;
1800     } else {
1801       ReturnType = Context.getObjCIdType();
1802     }
1803     VK = VK_PRValue;
1804     return false;
1805   }
1806 
1807   ReturnType = getMessageSendResultType(Receiver, ReceiverType, Method,
1808                                         isClassMessage, isSuperMessage);
1809   VK = Expr::getValueKindForType(Method->getReturnType());
1810 
1811   unsigned NumNamedArgs = Sel.getNumArgs();
1812   // Method might have more arguments than selector indicates. This is due
1813   // to addition of c-style arguments in method.
1814   if (Method->param_size() > Sel.getNumArgs())
1815     NumNamedArgs = Method->param_size();
1816   // FIXME. This need be cleaned up.
1817   if (Args.size() < NumNamedArgs) {
1818     Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1819         << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1820         << /*is non object*/ 0;
1821     return false;
1822   }
1823 
1824   // Compute the set of type arguments to be substituted into each parameter
1825   // type.
1826   std::optional<ArrayRef<QualType>> typeArgs =
1827       ReceiverType->getObjCSubstitutions(Method->getDeclContext());
1828   bool IsError = false;
1829   for (unsigned i = 0; i < NumNamedArgs; i++) {
1830     // We can't do any type-checking on a type-dependent argument.
1831     if (Args[i]->isTypeDependent())
1832       continue;
1833 
1834     Expr *argExpr = Args[i];
1835 
1836     ParmVarDecl *param = Method->parameters()[i];
1837     assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1838 
1839     if (param->hasAttr<NoEscapeAttr>() &&
1840         param->getType()->isBlockPointerType())
1841       if (auto *BE = dyn_cast<BlockExpr>(
1842               argExpr->IgnoreParenNoopCasts(Context)))
1843         BE->getBlockDecl()->setDoesNotEscape();
1844 
1845     // Strip the unbridged-cast placeholder expression off unless it's
1846     // a consumed argument.
1847     if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
1848         !param->hasAttr<CFConsumedAttr>())
1849       argExpr = stripARCUnbridgedCast(argExpr);
1850 
1851     // If the parameter is __unknown_anytype, infer its type
1852     // from the argument.
1853     if (param->getType() == Context.UnknownAnyTy) {
1854       QualType paramType;
1855       ExprResult argE = SemaRef.checkUnknownAnyArg(SelLoc, argExpr, paramType);
1856       if (argE.isInvalid()) {
1857         IsError = true;
1858       } else {
1859         Args[i] = argE.get();
1860 
1861         // Update the parameter type in-place.
1862         param->setType(paramType);
1863       }
1864       continue;
1865     }
1866 
1867     QualType origParamType = param->getType();
1868     QualType paramType = param->getType();
1869     if (typeArgs)
1870       paramType = paramType.substObjCTypeArgs(
1871                     Context,
1872                     *typeArgs,
1873                     ObjCSubstitutionContext::Parameter);
1874 
1875     if (SemaRef.RequireCompleteType(
1876             argExpr->getSourceRange().getBegin(), paramType,
1877             diag::err_call_incomplete_argument, argExpr))
1878       return true;
1879 
1880     InitializedEntity Entity
1881       = InitializedEntity::InitializeParameter(Context, param, paramType);
1882     ExprResult ArgE =
1883         SemaRef.PerformCopyInitialization(Entity, SourceLocation(), argExpr);
1884     if (ArgE.isInvalid())
1885       IsError = true;
1886     else {
1887       Args[i] = ArgE.getAs<Expr>();
1888 
1889       // If we are type-erasing a block to a block-compatible
1890       // Objective-C pointer type, we may need to extend the lifetime
1891       // of the block object.
1892       if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&
1893           Args[i]->getType()->isBlockPointerType() &&
1894           origParamType->isObjCObjectPointerType()) {
1895         ExprResult arg = Args[i];
1896         SemaRef.maybeExtendBlockObject(arg);
1897         Args[i] = arg.get();
1898       }
1899     }
1900   }
1901 
1902   // Promote additional arguments to variadic methods.
1903   if (Method->isVariadic()) {
1904     for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
1905       if (Args[i]->isTypeDependent())
1906         continue;
1907 
1908       ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion(
1909           Args[i], Sema::VariadicMethod, nullptr);
1910       IsError |= Arg.isInvalid();
1911       Args[i] = Arg.get();
1912     }
1913   } else {
1914     // Check for extra arguments to non-variadic methods.
1915     if (Args.size() != NumNamedArgs) {
1916       Diag(Args[NumNamedArgs]->getBeginLoc(),
1917            diag::err_typecheck_call_too_many_args)
1918           << 2 /*method*/ << NumNamedArgs << static_cast<unsigned>(Args.size())
1919           << Method->getSourceRange() << /*is non object*/ 0
1920           << SourceRange(Args[NumNamedArgs]->getBeginLoc(),
1921                          Args.back()->getEndLoc());
1922     }
1923   }
1924 
1925   SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args);
1926 
1927   // Do additional checkings on method.
1928   IsError |=
1929       CheckObjCMethodCall(Method, SelLoc, ArrayRef(Args.data(), Args.size()));
1930 
1931   return IsError;
1932 }
1933 
isSelfExpr(Expr * RExpr)1934 bool SemaObjC::isSelfExpr(Expr *RExpr) {
1935   // 'self' is objc 'self' in an objc method only.
1936   ObjCMethodDecl *Method = dyn_cast_or_null<ObjCMethodDecl>(
1937       SemaRef.CurContext->getNonClosureAncestor());
1938   return isSelfExpr(RExpr, Method);
1939 }
1940 
isSelfExpr(Expr * receiver,const ObjCMethodDecl * method)1941 bool SemaObjC::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {
1942   if (!method) return false;
1943 
1944   receiver = receiver->IgnoreParenLValueCasts();
1945   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
1946     if (DRE->getDecl() == method->getSelfDecl())
1947       return true;
1948   return false;
1949 }
1950 
1951 /// LookupMethodInType - Look up a method in an ObjCObjectType.
LookupMethodInObjectType(Selector sel,QualType type,bool isInstance)1952 ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type,
1953                                                    bool isInstance) {
1954   const ObjCObjectType *objType = type->castAs<ObjCObjectType>();
1955   if (ObjCInterfaceDecl *iface = objType->getInterface()) {
1956     // Look it up in the main interface (and categories, etc.)
1957     if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
1958       return method;
1959 
1960     // Okay, look for "private" methods declared in any
1961     // @implementations we've seen.
1962     if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
1963       return method;
1964   }
1965 
1966   // Check qualifiers.
1967   for (const auto *I : objType->quals())
1968     if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
1969       return method;
1970 
1971   return nullptr;
1972 }
1973 
1974 /// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
1975 /// list of a qualified objective pointer type.
LookupMethodInQualifiedType(Selector Sel,const ObjCObjectPointerType * OPT,bool Instance)1976 ObjCMethodDecl *SemaObjC::LookupMethodInQualifiedType(
1977     Selector Sel, const ObjCObjectPointerType *OPT, bool Instance) {
1978   ObjCMethodDecl *MD = nullptr;
1979   for (const auto *PROTO : OPT->quals()) {
1980     if ((MD = PROTO->lookupMethod(Sel, Instance))) {
1981       return MD;
1982     }
1983   }
1984   return nullptr;
1985 }
1986 
1987 /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
1988 /// objective C interface.  This is a property reference expression.
HandleExprPropertyRefExpr(const ObjCObjectPointerType * OPT,Expr * BaseExpr,SourceLocation OpLoc,DeclarationName MemberName,SourceLocation MemberLoc,SourceLocation SuperLoc,QualType SuperType,bool Super)1989 ExprResult SemaObjC::HandleExprPropertyRefExpr(
1990     const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc,
1991     DeclarationName MemberName, SourceLocation MemberLoc,
1992     SourceLocation SuperLoc, QualType SuperType, bool Super) {
1993   ASTContext &Context = getASTContext();
1994   const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
1995   ObjCInterfaceDecl *IFace = IFaceT->getDecl();
1996 
1997   if (!MemberName.isIdentifier()) {
1998     Diag(MemberLoc, diag::err_invalid_property_name)
1999       << MemberName << QualType(OPT, 0);
2000     return ExprError();
2001   }
2002 
2003   IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
2004 
2005   SourceRange BaseRange = Super? SourceRange(SuperLoc)
2006                                : BaseExpr->getSourceRange();
2007   if (SemaRef.RequireCompleteType(MemberLoc, OPT->getPointeeType(),
2008                                   diag::err_property_not_found_forward_class,
2009                                   MemberName, BaseRange))
2010     return ExprError();
2011 
2012   if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(
2013           Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
2014     // Check whether we can reference this property.
2015     if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2016       return ExprError();
2017     if (Super)
2018       return new (Context)
2019           ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2020                               OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2021     else
2022       return new (Context)
2023           ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2024                               OK_ObjCProperty, MemberLoc, BaseExpr);
2025   }
2026   // Check protocols on qualified interfaces.
2027   for (const auto *I : OPT->quals())
2028     if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
2029             Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
2030       // Check whether we can reference this property.
2031       if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2032         return ExprError();
2033 
2034       if (Super)
2035         return new (Context) ObjCPropertyRefExpr(
2036             PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,
2037             SuperLoc, SuperType);
2038       else
2039         return new (Context)
2040             ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2041                                 OK_ObjCProperty, MemberLoc, BaseExpr);
2042     }
2043   // If that failed, look for an "implicit" property by seeing if the nullary
2044   // selector is implemented.
2045 
2046   // FIXME: The logic for looking up nullary and unary selectors should be
2047   // shared with the code in ActOnInstanceMessage.
2048 
2049   Selector Sel = SemaRef.PP.getSelectorTable().getNullarySelector(Member);
2050   ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
2051 
2052   // May be found in property's qualified list.
2053   if (!Getter)
2054     Getter = LookupMethodInQualifiedType(Sel, OPT, true);
2055 
2056   // If this reference is in an @implementation, check for 'private' methods.
2057   if (!Getter)
2058     Getter = IFace->lookupPrivateMethod(Sel);
2059 
2060   if (Getter) {
2061     // Check if we can reference this property.
2062     if (SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2063       return ExprError();
2064   }
2065   // If we found a getter then this may be a valid dot-reference, we
2066   // will look for the matching setter, in case it is needed.
2067   Selector SetterSel = SelectorTable::constructSetterSelector(
2068       SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), Member);
2069   ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
2070 
2071   // May be found in property's qualified list.
2072   if (!Setter)
2073     Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
2074 
2075   if (!Setter) {
2076     // If this reference is in an @implementation, also check for 'private'
2077     // methods.
2078     Setter = IFace->lookupPrivateMethod(SetterSel);
2079   }
2080 
2081   if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2082     return ExprError();
2083 
2084   // Special warning if member name used in a property-dot for a setter accessor
2085   // does not use a property with same name; e.g. obj.X = ... for a property with
2086   // name 'x'.
2087   if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() &&
2088       !IFace->FindPropertyDeclaration(
2089           Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
2090       if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) {
2091         // Do not warn if user is using property-dot syntax to make call to
2092         // user named setter.
2093         if (!(PDecl->getPropertyAttributes() &
2094               ObjCPropertyAttribute::kind_setter))
2095           Diag(MemberLoc,
2096                diag::warn_property_access_suggest)
2097           << MemberName << QualType(OPT, 0) << PDecl->getName()
2098           << FixItHint::CreateReplacement(MemberLoc, PDecl->getName());
2099       }
2100   }
2101 
2102   if (Getter || Setter) {
2103     if (Super)
2104       return new (Context)
2105           ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2106                               OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2107     else
2108       return new (Context)
2109           ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2110                               OK_ObjCProperty, MemberLoc, BaseExpr);
2111 
2112   }
2113 
2114   // Attempt to correct for typos in property names.
2115   DeclFilterCCC<ObjCPropertyDecl> CCC{};
2116   if (TypoCorrection Corrected = SemaRef.CorrectTypo(
2117           DeclarationNameInfo(MemberName, MemberLoc), Sema::LookupOrdinaryName,
2118           nullptr, nullptr, CCC, Sema::CTK_ErrorRecovery, IFace, false, OPT)) {
2119     DeclarationName TypoResult = Corrected.getCorrection();
2120     if (TypoResult.isIdentifier() &&
2121         TypoResult.getAsIdentifierInfo() == Member) {
2122       // There is no need to try the correction if it is the same.
2123       NamedDecl *ChosenDecl =
2124         Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
2125       if (ChosenDecl && isa<ObjCPropertyDecl>(ChosenDecl))
2126         if (cast<ObjCPropertyDecl>(ChosenDecl)->isClassProperty()) {
2127           // This is a class property, we should not use the instance to
2128           // access it.
2129           Diag(MemberLoc, diag::err_class_property_found) << MemberName
2130           << OPT->getInterfaceDecl()->getName()
2131           << FixItHint::CreateReplacement(BaseExpr->getSourceRange(),
2132                                           OPT->getInterfaceDecl()->getName());
2133           return ExprError();
2134         }
2135     } else {
2136       SemaRef.diagnoseTypo(Corrected,
2137                            PDiag(diag::err_property_not_found_suggest)
2138                                << MemberName << QualType(OPT, 0));
2139       return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
2140                                        TypoResult, MemberLoc,
2141                                        SuperLoc, SuperType, Super);
2142     }
2143   }
2144   ObjCInterfaceDecl *ClassDeclared;
2145   if (ObjCIvarDecl *Ivar =
2146       IFace->lookupInstanceVariable(Member, ClassDeclared)) {
2147     QualType T = Ivar->getType();
2148     if (const ObjCObjectPointerType * OBJPT =
2149         T->getAsObjCInterfacePointerType()) {
2150       if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2151                                       diag::err_property_not_as_forward_class,
2152                                       MemberName, BaseExpr))
2153         return ExprError();
2154     }
2155     Diag(MemberLoc,
2156          diag::err_ivar_access_using_property_syntax_suggest)
2157     << MemberName << QualType(OPT, 0) << Ivar->getDeclName()
2158     << FixItHint::CreateReplacement(OpLoc, "->");
2159     return ExprError();
2160   }
2161 
2162   Diag(MemberLoc, diag::err_property_not_found)
2163     << MemberName << QualType(OPT, 0);
2164   if (Setter)
2165     Diag(Setter->getLocation(), diag::note_getter_unavailable)
2166           << MemberName << BaseExpr->getSourceRange();
2167   return ExprError();
2168 }
2169 
ActOnClassPropertyRefExpr(const IdentifierInfo & receiverName,const IdentifierInfo & propertyName,SourceLocation receiverNameLoc,SourceLocation propertyNameLoc)2170 ExprResult SemaObjC::ActOnClassPropertyRefExpr(
2171     const IdentifierInfo &receiverName, const IdentifierInfo &propertyName,
2172     SourceLocation receiverNameLoc, SourceLocation propertyNameLoc) {
2173   ASTContext &Context = getASTContext();
2174   const IdentifierInfo *receiverNamePtr = &receiverName;
2175   ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
2176                                                   receiverNameLoc);
2177 
2178   QualType SuperType;
2179   if (!IFace) {
2180     // If the "receiver" is 'super' in a method, handle it as an expression-like
2181     // property reference.
2182     if (receiverNamePtr->isStr("super")) {
2183       if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) {
2184         if (auto classDecl = CurMethod->getClassInterface()) {
2185           SuperType = QualType(classDecl->getSuperClassType(), 0);
2186           if (CurMethod->isInstanceMethod()) {
2187             if (SuperType.isNull()) {
2188               // The current class does not have a superclass.
2189               Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2190                 << CurMethod->getClassInterface()->getIdentifier();
2191               return ExprError();
2192             }
2193             QualType T = Context.getObjCObjectPointerType(SuperType);
2194 
2195             return HandleExprPropertyRefExpr(T->castAs<ObjCObjectPointerType>(),
2196                                              /*BaseExpr*/nullptr,
2197                                              SourceLocation()/*OpLoc*/,
2198                                              &propertyName,
2199                                              propertyNameLoc,
2200                                              receiverNameLoc, T, true);
2201           }
2202 
2203           // Otherwise, if this is a class method, try dispatching to our
2204           // superclass.
2205           IFace = CurMethod->getClassInterface()->getSuperClass();
2206         }
2207       }
2208     }
2209 
2210     if (!IFace) {
2211       Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2212                                                        << tok::l_paren;
2213       return ExprError();
2214     }
2215   }
2216 
2217   Selector GetterSel;
2218   Selector SetterSel;
2219   if (auto PD = IFace->FindPropertyDeclaration(
2220           &propertyName, ObjCPropertyQueryKind::OBJC_PR_query_class)) {
2221     GetterSel = PD->getGetterName();
2222     SetterSel = PD->getSetterName();
2223   } else {
2224     GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2225     SetterSel = SelectorTable::constructSetterSelector(
2226         SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(),
2227         &propertyName);
2228   }
2229 
2230   // Search for a declared property first.
2231   ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel);
2232 
2233   // If this reference is in an @implementation, check for 'private' methods.
2234   if (!Getter)
2235     Getter = IFace->lookupPrivateClassMethod(GetterSel);
2236 
2237   if (Getter) {
2238     // FIXME: refactor/share with ActOnMemberReference().
2239     // Check if we can reference this property.
2240     if (SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2241       return ExprError();
2242   }
2243 
2244   // Look for the matching setter, in case it is needed.
2245   ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
2246   if (!Setter) {
2247     // If this reference is in an @implementation, also check for 'private'
2248     // methods.
2249     Setter = IFace->lookupPrivateClassMethod(SetterSel);
2250   }
2251   // Look through local category implementations associated with the class.
2252   if (!Setter)
2253     Setter = IFace->getCategoryClassMethod(SetterSel);
2254 
2255   if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2256     return ExprError();
2257 
2258   if (Getter || Setter) {
2259     if (!SuperType.isNull())
2260       return new (Context)
2261           ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2262                               OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
2263                               SuperType);
2264 
2265     return new (Context) ObjCPropertyRefExpr(
2266         Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
2267         propertyNameLoc, receiverNameLoc, IFace);
2268   }
2269   return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
2270                      << &propertyName << Context.getObjCInterfaceType(IFace));
2271 }
2272 
2273 namespace {
2274 
2275 class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {
2276  public:
ObjCInterfaceOrSuperCCC(ObjCMethodDecl * Method)2277   ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) {
2278     // Determine whether "super" is acceptable in the current context.
2279     if (Method && Method->getClassInterface())
2280       WantObjCSuper = Method->getClassInterface()->getSuperClass();
2281   }
2282 
ValidateCandidate(const TypoCorrection & candidate)2283   bool ValidateCandidate(const TypoCorrection &candidate) override {
2284     return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||
2285         candidate.isKeyword("super");
2286   }
2287 
clone()2288   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2289     return std::make_unique<ObjCInterfaceOrSuperCCC>(*this);
2290   }
2291 };
2292 
2293 } // end anonymous namespace
2294 
2295 SemaObjC::ObjCMessageKind
getObjCMessageKind(Scope * S,IdentifierInfo * Name,SourceLocation NameLoc,bool IsSuper,bool HasTrailingDot,ParsedType & ReceiverType)2296 SemaObjC::getObjCMessageKind(Scope *S, IdentifierInfo *Name,
2297                              SourceLocation NameLoc, bool IsSuper,
2298                              bool HasTrailingDot, ParsedType &ReceiverType) {
2299   ASTContext &Context = getASTContext();
2300   ReceiverType = nullptr;
2301 
2302   // If the identifier is "super" and there is no trailing dot, we're
2303   // messaging super. If the identifier is "super" and there is a
2304   // trailing dot, it's an instance message.
2305   if (IsSuper && S->isInObjcMethodScope())
2306     return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;
2307 
2308   LookupResult Result(SemaRef, Name, NameLoc, Sema::LookupOrdinaryName);
2309   SemaRef.LookupName(Result, S);
2310 
2311   switch (Result.getResultKind()) {
2312   case LookupResult::NotFound:
2313     // Normal name lookup didn't find anything. If we're in an
2314     // Objective-C method, look for ivars. If we find one, we're done!
2315     // FIXME: This is a hack. Ivar lookup should be part of normal
2316     // lookup.
2317     if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2318       if (!Method->getClassInterface()) {
2319         // Fall back: let the parser try to parse it as an instance message.
2320         return ObjCInstanceMessage;
2321       }
2322 
2323       ObjCInterfaceDecl *ClassDeclared;
2324       if (Method->getClassInterface()->lookupInstanceVariable(Name,
2325                                                               ClassDeclared))
2326         return ObjCInstanceMessage;
2327     }
2328 
2329     // Break out; we'll perform typo correction below.
2330     break;
2331 
2332   case LookupResult::NotFoundInCurrentInstantiation:
2333   case LookupResult::FoundOverloaded:
2334   case LookupResult::FoundUnresolvedValue:
2335   case LookupResult::Ambiguous:
2336     Result.suppressDiagnostics();
2337     return ObjCInstanceMessage;
2338 
2339   case LookupResult::Found: {
2340     // If the identifier is a class or not, and there is a trailing dot,
2341     // it's an instance message.
2342     if (HasTrailingDot)
2343       return ObjCInstanceMessage;
2344     // We found something. If it's a type, then we have a class
2345     // message. Otherwise, it's an instance message.
2346     NamedDecl *ND = Result.getFoundDecl();
2347     QualType T;
2348     if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
2349       T = Context.getObjCInterfaceType(Class);
2350     else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {
2351       T = Context.getTypeDeclType(Type);
2352       SemaRef.DiagnoseUseOfDecl(Type, NameLoc);
2353     }
2354     else
2355       return ObjCInstanceMessage;
2356 
2357     //  We have a class message, and T is the type we're
2358     //  messaging. Build source-location information for it.
2359     TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2360     ReceiverType = SemaRef.CreateParsedType(T, TSInfo);
2361     return ObjCClassMessage;
2362   }
2363   }
2364 
2365   ObjCInterfaceOrSuperCCC CCC(SemaRef.getCurMethodDecl());
2366   if (TypoCorrection Corrected = SemaRef.CorrectTypo(
2367           Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
2368           Sema::CTK_ErrorRecovery, nullptr, false, nullptr, false)) {
2369     if (Corrected.isKeyword()) {
2370       // If we've found the keyword "super" (the only keyword that would be
2371       // returned by CorrectTypo), this is a send to super.
2372       SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)
2373                                           << Name);
2374       return ObjCSuperMessage;
2375     } else if (ObjCInterfaceDecl *Class =
2376                    Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
2377       // If we found a declaration, correct when it refers to an Objective-C
2378       // class.
2379       SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)
2380                                           << Name);
2381       QualType T = Context.getObjCInterfaceType(Class);
2382       TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2383       ReceiverType = SemaRef.CreateParsedType(T, TSInfo);
2384       return ObjCClassMessage;
2385     }
2386   }
2387 
2388   // Fall back: let the parser try to parse it as an instance message.
2389   return ObjCInstanceMessage;
2390 }
2391 
ActOnSuperMessage(Scope * S,SourceLocation SuperLoc,Selector Sel,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg Args)2392 ExprResult SemaObjC::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
2393                                        Selector Sel, SourceLocation LBracLoc,
2394                                        ArrayRef<SourceLocation> SelectorLocs,
2395                                        SourceLocation RBracLoc,
2396                                        MultiExprArg Args) {
2397   ASTContext &Context = getASTContext();
2398   // Determine whether we are inside a method or not.
2399   ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc);
2400   if (!Method) {
2401     Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2402     return ExprError();
2403   }
2404 
2405   ObjCInterfaceDecl *Class = Method->getClassInterface();
2406   if (!Class) {
2407     Diag(SuperLoc, diag::err_no_super_class_message)
2408       << Method->getDeclName();
2409     return ExprError();
2410   }
2411 
2412   QualType SuperTy(Class->getSuperClassType(), 0);
2413   if (SuperTy.isNull()) {
2414     // The current class does not have a superclass.
2415     Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2416       << Class->getIdentifier();
2417     return ExprError();
2418   }
2419 
2420   // We are in a method whose class has a superclass, so 'super'
2421   // is acting as a keyword.
2422   if (Method->getSelector() == Sel)
2423     SemaRef.getCurFunction()->ObjCShouldCallSuper = false;
2424 
2425   if (Method->isInstanceMethod()) {
2426     // Since we are in an instance method, this is an instance
2427     // message to the superclass instance.
2428     SuperTy = Context.getObjCObjectPointerType(SuperTy);
2429     return BuildInstanceMessage(nullptr, SuperTy, SuperLoc,
2430                                 Sel, /*Method=*/nullptr,
2431                                 LBracLoc, SelectorLocs, RBracLoc, Args);
2432   }
2433 
2434   // Since we are in a class method, this is a class message to
2435   // the superclass.
2436   return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,
2437                            SuperTy,
2438                            SuperLoc, Sel, /*Method=*/nullptr,
2439                            LBracLoc, SelectorLocs, RBracLoc, Args);
2440 }
2441 
BuildClassMessageImplicit(QualType ReceiverType,bool isSuperReceiver,SourceLocation Loc,Selector Sel,ObjCMethodDecl * Method,MultiExprArg Args)2442 ExprResult SemaObjC::BuildClassMessageImplicit(QualType ReceiverType,
2443                                                bool isSuperReceiver,
2444                                                SourceLocation Loc, Selector Sel,
2445                                                ObjCMethodDecl *Method,
2446                                                MultiExprArg Args) {
2447   ASTContext &Context = getASTContext();
2448   TypeSourceInfo *receiverTypeInfo = nullptr;
2449   if (!ReceiverType.isNull())
2450     receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2451 
2452   assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&
2453          "Either the super receiver location needs to be valid or the receiver "
2454          "needs valid type source information");
2455   return BuildClassMessage(receiverTypeInfo, ReceiverType,
2456                           /*SuperLoc=*/isSuperReceiver ? Loc : SourceLocation(),
2457                            Sel, Method, Loc, Loc, Loc, Args,
2458                            /*isImplicit=*/true);
2459 }
2460 
applyCocoaAPICheck(Sema & S,const ObjCMessageExpr * Msg,unsigned DiagID,bool (* refactor)(const ObjCMessageExpr *,const NSAPI &,edit::Commit &))2461 static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,
2462                                unsigned DiagID,
2463                                bool (*refactor)(const ObjCMessageExpr *,
2464                                               const NSAPI &, edit::Commit &)) {
2465   SourceLocation MsgLoc = Msg->getExprLoc();
2466   if (S.Diags.isIgnored(DiagID, MsgLoc))
2467     return;
2468 
2469   SourceManager &SM = S.SourceMgr;
2470   edit::Commit ECommit(SM, S.LangOpts);
2471   if (refactor(Msg, *S.ObjC().NSAPIObj, ECommit)) {
2472     auto Builder = S.Diag(MsgLoc, DiagID)
2473                    << Msg->getSelector() << Msg->getSourceRange();
2474     // FIXME: Don't emit diagnostic at all if fixits are non-commitable.
2475     if (!ECommit.isCommitable())
2476       return;
2477     for (edit::Commit::edit_iterator
2478            I = ECommit.edit_begin(), E = ECommit.edit_end(); I != E; ++I) {
2479       const edit::Commit::Edit &Edit = *I;
2480       switch (Edit.Kind) {
2481       case edit::Commit::Act_Insert:
2482         Builder.AddFixItHint(FixItHint::CreateInsertion(Edit.OrigLoc,
2483                                                         Edit.Text,
2484                                                         Edit.BeforePrev));
2485         break;
2486       case edit::Commit::Act_InsertFromRange:
2487         Builder.AddFixItHint(
2488             FixItHint::CreateInsertionFromRange(Edit.OrigLoc,
2489                                                 Edit.getInsertFromRange(SM),
2490                                                 Edit.BeforePrev));
2491         break;
2492       case edit::Commit::Act_Remove:
2493         Builder.AddFixItHint(FixItHint::CreateRemoval(Edit.getFileRange(SM)));
2494         break;
2495       }
2496     }
2497   }
2498 }
2499 
checkCocoaAPI(Sema & S,const ObjCMessageExpr * Msg)2500 static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {
2501   applyCocoaAPICheck(S, Msg, diag::warn_objc_redundant_literal_use,
2502                      edit::rewriteObjCRedundantCallWithLiteral);
2503 }
2504 
checkFoundationAPI(Sema & S,SourceLocation Loc,const ObjCMethodDecl * Method,ArrayRef<Expr * > Args,QualType ReceiverType,bool IsClassObjectCall)2505 static void checkFoundationAPI(Sema &S, SourceLocation Loc,
2506                                const ObjCMethodDecl *Method,
2507                                ArrayRef<Expr *> Args, QualType ReceiverType,
2508                                bool IsClassObjectCall) {
2509   // Check if this is a performSelector method that uses a selector that returns
2510   // a record or a vector type.
2511   if (Method->getSelector().getMethodFamily() != OMF_performSelector ||
2512       Args.empty())
2513     return;
2514   const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2515   if (!SE)
2516     return;
2517   ObjCMethodDecl *ImpliedMethod;
2518   if (!IsClassObjectCall) {
2519     const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();
2520     if (!OPT || !OPT->getInterfaceDecl())
2521       return;
2522     ImpliedMethod =
2523         OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2524     if (!ImpliedMethod)
2525       ImpliedMethod =
2526           OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2527   } else {
2528     const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();
2529     if (!IT)
2530       return;
2531     ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2532     if (!ImpliedMethod)
2533       ImpliedMethod =
2534           IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2535   }
2536   if (!ImpliedMethod)
2537     return;
2538   QualType Ret = ImpliedMethod->getReturnType();
2539   if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2540     S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2541         << Method->getSelector()
2542         << (!Ret->isRecordType()
2543                 ? /*Vector*/ 2
2544                 : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);
2545     S.Diag(ImpliedMethod->getBeginLoc(),
2546            diag::note_objc_unsafe_perform_selector_method_declared_here)
2547         << ImpliedMethod->getSelector() << Ret;
2548   }
2549 }
2550 
2551 /// Diagnose use of %s directive in an NSString which is being passed
2552 /// as formatting string to formatting method.
2553 static void
DiagnoseCStringFormatDirectiveInObjCAPI(Sema & S,ObjCMethodDecl * Method,Selector Sel,Expr ** Args,unsigned NumArgs)2554 DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S,
2555                                         ObjCMethodDecl *Method,
2556                                         Selector Sel,
2557                                         Expr **Args, unsigned NumArgs) {
2558   unsigned Idx = 0;
2559   bool Format = false;
2560   ObjCStringFormatFamily SFFamily = Sel.getStringFormatFamily();
2561   if (SFFamily == ObjCStringFormatFamily::SFF_NSString) {
2562     Idx = 0;
2563     Format = true;
2564   }
2565   else if (Method) {
2566     for (const auto *I : Method->specific_attrs<FormatAttr>()) {
2567       if (S.ObjC().GetFormatNSStringIdx(I, Idx)) {
2568         Format = true;
2569         break;
2570       }
2571     }
2572   }
2573   if (!Format || NumArgs <= Idx)
2574     return;
2575 
2576   Expr *FormatExpr = Args[Idx];
2577   if (ObjCStringLiteral *OSL =
2578       dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) {
2579     StringLiteral *FormatString = OSL->getString();
2580     if (S.FormatStringHasSArg(FormatString)) {
2581       S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)
2582         << "%s" << 0 << 0;
2583       if (Method)
2584         S.Diag(Method->getLocation(), diag::note_method_declared_at)
2585           << Method->getDeclName();
2586     }
2587   }
2588 }
2589 
2590 /// Build an Objective-C class message expression.
2591 ///
2592 /// This routine takes care of both normal class messages and
2593 /// class messages to the superclass.
2594 ///
2595 /// \param ReceiverTypeInfo Type source information that describes the
2596 /// receiver of this message. This may be NULL, in which case we are
2597 /// sending to the superclass and \p SuperLoc must be a valid source
2598 /// location.
2599 
2600 /// \param ReceiverType The type of the object receiving the
2601 /// message. When \p ReceiverTypeInfo is non-NULL, this is the same
2602 /// type as that refers to. For a superclass send, this is the type of
2603 /// the superclass.
2604 ///
2605 /// \param SuperLoc The location of the "super" keyword in a
2606 /// superclass message.
2607 ///
2608 /// \param Sel The selector to which the message is being sent.
2609 ///
2610 /// \param Method The method that this class message is invoking, if
2611 /// already known.
2612 ///
2613 /// \param LBracLoc The location of the opening square bracket ']'.
2614 ///
2615 /// \param RBracLoc The location of the closing square bracket ']'.
2616 ///
2617 /// \param ArgsIn The message arguments.
BuildClassMessage(TypeSourceInfo * ReceiverTypeInfo,QualType ReceiverType,SourceLocation SuperLoc,Selector Sel,ObjCMethodDecl * Method,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg ArgsIn,bool isImplicit)2618 ExprResult SemaObjC::BuildClassMessage(
2619     TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType,
2620     SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method,
2621     SourceLocation LBracLoc, ArrayRef<SourceLocation> SelectorLocs,
2622     SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) {
2623   ASTContext &Context = getASTContext();
2624   SourceLocation Loc = SuperLoc.isValid()? SuperLoc
2625     : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
2626   if (LBracLoc.isInvalid()) {
2627     Diag(Loc, diag::err_missing_open_square_message_send)
2628       << FixItHint::CreateInsertion(Loc, "[");
2629     LBracLoc = Loc;
2630   }
2631   ArrayRef<SourceLocation> SelectorSlotLocs;
2632   if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2633     SelectorSlotLocs = SelectorLocs;
2634   else
2635     SelectorSlotLocs = Loc;
2636   SourceLocation SelLoc = SelectorSlotLocs.front();
2637 
2638   if (ReceiverType->isDependentType()) {
2639     // If the receiver type is dependent, we can't type-check anything
2640     // at this point. Build a dependent expression.
2641     unsigned NumArgs = ArgsIn.size();
2642     Expr **Args = ArgsIn.data();
2643     assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2644     return ObjCMessageExpr::Create(Context, ReceiverType, VK_PRValue, LBracLoc,
2645                                    ReceiverTypeInfo, Sel, SelectorLocs,
2646                                    /*Method=*/nullptr, ArrayRef(Args, NumArgs),
2647                                    RBracLoc, isImplicit);
2648   }
2649 
2650   // Find the class to which we are sending this message.
2651   ObjCInterfaceDecl *Class = nullptr;
2652   const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
2653   if (!ClassType || !(Class = ClassType->getInterface())) {
2654     Diag(Loc, diag::err_invalid_receiver_class_message)
2655       << ReceiverType;
2656     return ExprError();
2657   }
2658   assert(Class && "We don't know which class we're messaging?");
2659   // objc++ diagnoses during typename annotation.
2660   if (!getLangOpts().CPlusPlus)
2661     (void)SemaRef.DiagnoseUseOfDecl(Class, SelectorSlotLocs);
2662   // Find the method we are messaging.
2663   if (!Method) {
2664     SourceRange TypeRange
2665       = SuperLoc.isValid()? SourceRange(SuperLoc)
2666                           : ReceiverTypeInfo->getTypeLoc().getSourceRange();
2667     if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),
2668                                     (getLangOpts().ObjCAutoRefCount
2669                                          ? diag::err_arc_receiver_forward_class
2670                                          : diag::warn_receiver_forward_class),
2671                                     TypeRange)) {
2672       // A forward class used in messaging is treated as a 'Class'
2673       Method = LookupFactoryMethodInGlobalPool(Sel,
2674                                                SourceRange(LBracLoc, RBracLoc));
2675       if (Method && !getLangOpts().ObjCAutoRefCount)
2676         Diag(Method->getLocation(), diag::note_method_sent_forward_class)
2677           << Method->getDeclName();
2678     }
2679     if (!Method)
2680       Method = Class->lookupClassMethod(Sel);
2681 
2682     // If we have an implementation in scope, check "private" methods.
2683     if (!Method)
2684       Method = Class->lookupPrivateClassMethod(Sel);
2685 
2686     if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr,
2687                                             false, false, Class))
2688       return ExprError();
2689   }
2690 
2691   // Check the argument types and determine the result type.
2692   QualType ReturnType;
2693   ExprValueKind VK = VK_PRValue;
2694 
2695   unsigned NumArgs = ArgsIn.size();
2696   Expr **Args = ArgsIn.data();
2697   if (CheckMessageArgumentTypes(/*Receiver=*/nullptr, ReceiverType,
2698                                 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
2699                                 Method, true, SuperLoc.isValid(), LBracLoc,
2700                                 RBracLoc, SourceRange(), ReturnType, VK))
2701     return ExprError();
2702 
2703   if (Method && !Method->getReturnType()->isVoidType() &&
2704       SemaRef.RequireCompleteType(
2705           LBracLoc, Method->getReturnType(),
2706           diag::err_illegal_message_expr_incomplete_type))
2707     return ExprError();
2708 
2709   if (Method && Method->isDirectMethod() && SuperLoc.isValid()) {
2710     Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2711         << FixItHint::CreateReplacement(
2712                SuperLoc, getLangOpts().ObjCAutoRefCount
2713                              ? "self"
2714                              : Method->getClassInterface()->getName());
2715     Diag(Method->getLocation(), diag::note_direct_method_declared_at)
2716         << Method->getDeclName();
2717   }
2718 
2719   // Warn about explicit call of +initialize on its own class. But not on 'super'.
2720   if (Method && Method->getMethodFamily() == OMF_initialize) {
2721     if (!SuperLoc.isValid()) {
2722       const ObjCInterfaceDecl *ID =
2723         dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
2724       if (ID == Class) {
2725         Diag(Loc, diag::warn_direct_initialize_call);
2726         Diag(Method->getLocation(), diag::note_method_declared_at)
2727           << Method->getDeclName();
2728       }
2729     } else if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) {
2730       // [super initialize] is allowed only within an +initialize implementation
2731       if (CurMeth->getMethodFamily() != OMF_initialize) {
2732         Diag(Loc, diag::warn_direct_super_initialize_call);
2733         Diag(Method->getLocation(), diag::note_method_declared_at)
2734           << Method->getDeclName();
2735         Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2736         << CurMeth->getDeclName();
2737       }
2738     }
2739   }
2740 
2741   DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs);
2742 
2743   // Construct the appropriate ObjCMessageExpr.
2744   ObjCMessageExpr *Result;
2745   if (SuperLoc.isValid())
2746     Result = ObjCMessageExpr::Create(
2747         Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false,
2748         ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
2749         RBracLoc, isImplicit);
2750   else {
2751     Result = ObjCMessageExpr::Create(
2752         Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2753         Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
2754     if (!isImplicit)
2755       checkCocoaAPI(SemaRef, Result);
2756   }
2757   if (Method)
2758     checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs),
2759                        ReceiverType, /*IsClassObjectCall=*/true);
2760   return SemaRef.MaybeBindToTemporary(Result);
2761 }
2762 
2763 // ActOnClassMessage - used for both unary and keyword messages.
2764 // ArgExprs is optional - if it is present, the number of expressions
2765 // is obtained from Sel.getNumArgs().
ActOnClassMessage(Scope * S,ParsedType Receiver,Selector Sel,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg Args)2766 ExprResult SemaObjC::ActOnClassMessage(Scope *S, ParsedType Receiver,
2767                                        Selector Sel, SourceLocation LBracLoc,
2768                                        ArrayRef<SourceLocation> SelectorLocs,
2769                                        SourceLocation RBracLoc,
2770                                        MultiExprArg Args) {
2771   ASTContext &Context = getASTContext();
2772   TypeSourceInfo *ReceiverTypeInfo;
2773   QualType ReceiverType =
2774       SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2775   if (ReceiverType.isNull())
2776     return ExprError();
2777 
2778   if (!ReceiverTypeInfo)
2779     ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2780 
2781   return BuildClassMessage(ReceiverTypeInfo, ReceiverType,
2782                            /*SuperLoc=*/SourceLocation(), Sel,
2783                            /*Method=*/nullptr, LBracLoc, SelectorLocs, RBracLoc,
2784                            Args);
2785 }
2786 
BuildInstanceMessageImplicit(Expr * Receiver,QualType ReceiverType,SourceLocation Loc,Selector Sel,ObjCMethodDecl * Method,MultiExprArg Args)2787 ExprResult SemaObjC::BuildInstanceMessageImplicit(
2788     Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel,
2789     ObjCMethodDecl *Method, MultiExprArg Args) {
2790   return BuildInstanceMessage(Receiver, ReceiverType,
2791                               /*SuperLoc=*/!Receiver ? Loc : SourceLocation(),
2792                               Sel, Method, Loc, Loc, Loc, Args,
2793                               /*isImplicit=*/true);
2794 }
2795 
isMethodDeclaredInRootProtocol(Sema & S,const ObjCMethodDecl * M)2796 static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {
2797   if (!S.ObjC().NSAPIObj)
2798     return false;
2799   const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());
2800   if (!Protocol)
2801     return false;
2802   const IdentifierInfo *II =
2803       S.ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
2804   if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2805           S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(),
2806                              Sema::LookupOrdinaryName))) {
2807     for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
2808       if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2809         return true;
2810     }
2811   }
2812   return false;
2813 }
2814 
2815 /// Build an Objective-C instance message expression.
2816 ///
2817 /// This routine takes care of both normal instance messages and
2818 /// instance messages to the superclass instance.
2819 ///
2820 /// \param Receiver The expression that computes the object that will
2821 /// receive this message. This may be empty, in which case we are
2822 /// sending to the superclass instance and \p SuperLoc must be a valid
2823 /// source location.
2824 ///
2825 /// \param ReceiverType The (static) type of the object receiving the
2826 /// message. When a \p Receiver expression is provided, this is the
2827 /// same type as that expression. For a superclass instance send, this
2828 /// is a pointer to the type of the superclass.
2829 ///
2830 /// \param SuperLoc The location of the "super" keyword in a
2831 /// superclass instance message.
2832 ///
2833 /// \param Sel The selector to which the message is being sent.
2834 ///
2835 /// \param Method The method that this instance message is invoking, if
2836 /// already known.
2837 ///
2838 /// \param LBracLoc The location of the opening square bracket ']'.
2839 ///
2840 /// \param RBracLoc The location of the closing square bracket ']'.
2841 ///
2842 /// \param ArgsIn The message arguments.
BuildInstanceMessage(Expr * Receiver,QualType ReceiverType,SourceLocation SuperLoc,Selector Sel,ObjCMethodDecl * Method,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg ArgsIn,bool isImplicit)2843 ExprResult SemaObjC::BuildInstanceMessage(
2844     Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc,
2845     Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc,
2846     ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc,
2847     MultiExprArg ArgsIn, bool isImplicit) {
2848   assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "
2849                                              "SuperLoc must be valid so we can "
2850                                              "use it instead.");
2851   ASTContext &Context = getASTContext();
2852 
2853   // The location of the receiver.
2854   SourceLocation Loc = SuperLoc.isValid() ? SuperLoc : Receiver->getBeginLoc();
2855   SourceRange RecRange =
2856       SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
2857   ArrayRef<SourceLocation> SelectorSlotLocs;
2858   if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2859     SelectorSlotLocs = SelectorLocs;
2860   else
2861     SelectorSlotLocs = Loc;
2862   SourceLocation SelLoc = SelectorSlotLocs.front();
2863 
2864   if (LBracLoc.isInvalid()) {
2865     Diag(Loc, diag::err_missing_open_square_message_send)
2866       << FixItHint::CreateInsertion(Loc, "[");
2867     LBracLoc = Loc;
2868   }
2869 
2870   // If we have a receiver expression, perform appropriate promotions
2871   // and determine receiver type.
2872   if (Receiver) {
2873     if (Receiver->hasPlaceholderType()) {
2874       ExprResult Result;
2875       if (Receiver->getType() == Context.UnknownAnyTy)
2876         Result =
2877             SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
2878       else
2879         Result = SemaRef.CheckPlaceholderExpr(Receiver);
2880       if (Result.isInvalid()) return ExprError();
2881       Receiver = Result.get();
2882     }
2883 
2884     if (Receiver->isTypeDependent()) {
2885       // If the receiver is type-dependent, we can't type-check anything
2886       // at this point. Build a dependent expression.
2887       unsigned NumArgs = ArgsIn.size();
2888       Expr **Args = ArgsIn.data();
2889       assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2890       return ObjCMessageExpr::Create(
2891           Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,
2892           SelectorLocs, /*Method=*/nullptr, ArrayRef(Args, NumArgs), RBracLoc,
2893           isImplicit);
2894     }
2895 
2896     // If necessary, apply function/array conversion to the receiver.
2897     // C99 6.7.5.3p[7,8].
2898     ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Receiver);
2899     if (Result.isInvalid())
2900       return ExprError();
2901     Receiver = Result.get();
2902     ReceiverType = Receiver->getType();
2903 
2904     // If the receiver is an ObjC pointer, a block pointer, or an
2905     // __attribute__((NSObject)) pointer, we don't need to do any
2906     // special conversion in order to look up a receiver.
2907     if (ReceiverType->isObjCRetainableType()) {
2908       // do nothing
2909     } else if (!getLangOpts().ObjCAutoRefCount &&
2910                !Context.getObjCIdType().isNull() &&
2911                (ReceiverType->isPointerType() ||
2912                 ReceiverType->isIntegerType())) {
2913       // Implicitly convert integers and pointers to 'id' but emit a warning.
2914       // But not in ARC.
2915       Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
2916       if (ReceiverType->isPointerType()) {
2917         Receiver = SemaRef
2918                        .ImpCastExprToType(Receiver, Context.getObjCIdType(),
2919                                           CK_CPointerToObjCPointerCast)
2920                        .get();
2921       } else {
2922         // TODO: specialized warning on null receivers?
2923         bool IsNull = Receiver->isNullPointerConstant(Context,
2924                                               Expr::NPC_ValueDependentIsNull);
2925         CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
2926         Receiver =
2927             SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
2928                 .get();
2929       }
2930       ReceiverType = Receiver->getType();
2931     } else if (getLangOpts().CPlusPlus) {
2932       // The receiver must be a complete type.
2933       if (SemaRef.RequireCompleteType(Loc, Receiver->getType(),
2934                                       diag::err_incomplete_receiver_type))
2935         return ExprError();
2936 
2937       ExprResult result =
2938           SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
2939       if (result.isUsable()) {
2940         Receiver = result.get();
2941         ReceiverType = Receiver->getType();
2942       }
2943     }
2944   }
2945 
2946   // There's a somewhat weird interaction here where we assume that we
2947   // won't actually have a method unless we also don't need to do some
2948   // of the more detailed type-checking on the receiver.
2949 
2950   if (!Method) {
2951     // Handle messages to id and __kindof types (where we use the
2952     // global method pool).
2953     const ObjCObjectType *typeBound = nullptr;
2954     bool receiverIsIdLike = ReceiverType->isObjCIdOrObjectKindOfType(Context,
2955                                                                      typeBound);
2956     if (receiverIsIdLike || ReceiverType->isBlockPointerType() ||
2957         (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
2958       SmallVector<ObjCMethodDecl*, 4> Methods;
2959       // If we have a type bound, further filter the methods.
2960       CollectMultipleMethodsInGlobalPool(Sel, Methods, true/*InstanceFirst*/,
2961                                          true/*CheckTheOther*/, typeBound);
2962       if (!Methods.empty()) {
2963         // We choose the first method as the initial candidate, then try to
2964         // select a better one.
2965         Method = Methods[0];
2966 
2967         if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(
2968                 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
2969           Method = BestMethod;
2970 
2971         if (!AreMultipleMethodsInGlobalPool(Sel, Method,
2972                                             SourceRange(LBracLoc, RBracLoc),
2973                                             receiverIsIdLike, Methods))
2974           SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs);
2975       }
2976     } else if (ReceiverType->isObjCClassOrClassKindOfType() ||
2977                ReceiverType->isObjCQualifiedClassType()) {
2978       // Handle messages to Class.
2979       // We allow sending a message to a qualified Class ("Class<foo>"), which
2980       // is ok as long as one of the protocols implements the selector (if not,
2981       // warn).
2982       if (!ReceiverType->isObjCClassOrClassKindOfType()) {
2983         const ObjCObjectPointerType *QClassTy
2984           = ReceiverType->getAsObjCQualifiedClassType();
2985         // Search protocols for class methods.
2986         Method = LookupMethodInQualifiedType(Sel, QClassTy, false);
2987         if (!Method) {
2988           Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
2989           // warn if instance method found for a Class message.
2990           if (Method && !isMethodDeclaredInRootProtocol(SemaRef, Method)) {
2991             Diag(SelLoc, diag::warn_instance_method_on_class_found)
2992               << Method->getSelector() << Sel;
2993             Diag(Method->getLocation(), diag::note_method_declared_at)
2994               << Method->getDeclName();
2995           }
2996         }
2997       } else {
2998         if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) {
2999           if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
3000             // As a guess, try looking for the method in the current interface.
3001             // This very well may not produce the "right" method.
3002 
3003             // First check the public methods in the class interface.
3004             Method = ClassDecl->lookupClassMethod(Sel);
3005 
3006             if (!Method)
3007               Method = ClassDecl->lookupPrivateClassMethod(Sel);
3008 
3009             if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3010               return ExprError();
3011           }
3012         }
3013         if (!Method) {
3014           // If not messaging 'self', look for any factory method named 'Sel'.
3015           if (!Receiver || !isSelfExpr(Receiver)) {
3016             // If no class (factory) method was found, check if an _instance_
3017             // method of the same name exists in the root class only.
3018             SmallVector<ObjCMethodDecl*, 4> Methods;
3019             CollectMultipleMethodsInGlobalPool(Sel, Methods,
3020                                                false/*InstanceFirst*/,
3021                                                true/*CheckTheOther*/);
3022             if (!Methods.empty()) {
3023               // We choose the first method as the initial candidate, then try
3024               // to select a better one.
3025               Method = Methods[0];
3026 
3027               // If we find an instance method, emit warning.
3028               if (Method->isInstanceMethod()) {
3029                 if (const ObjCInterfaceDecl *ID =
3030                     dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
3031                   if (ID->getSuperClass())
3032                     Diag(SelLoc, diag::warn_root_inst_method_not_found)
3033                         << Sel << SourceRange(LBracLoc, RBracLoc);
3034                 }
3035               }
3036 
3037               if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(
3038                       Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3039                 Method = BestMethod;
3040             }
3041           }
3042         }
3043       }
3044     } else {
3045       ObjCInterfaceDecl *ClassDecl = nullptr;
3046 
3047       // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
3048       // long as one of the protocols implements the selector (if not, warn).
3049       // And as long as message is not deprecated/unavailable (warn if it is).
3050       if (const ObjCObjectPointerType *QIdTy
3051                                    = ReceiverType->getAsObjCQualifiedIdType()) {
3052         // Search protocols for instance methods.
3053         Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
3054         if (!Method)
3055           Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
3056         if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3057           return ExprError();
3058       } else if (const ObjCObjectPointerType *OCIType
3059                    = ReceiverType->getAsObjCInterfacePointerType()) {
3060         // We allow sending a message to a pointer to an interface (an object).
3061         ClassDecl = OCIType->getInterfaceDecl();
3062 
3063         // Try to complete the type. Under ARC, this is a hard error from which
3064         // we don't try to recover.
3065         // FIXME: In the non-ARC case, this will still be a hard error if the
3066         // definition is found in a module that's not visible.
3067         const ObjCInterfaceDecl *forwardClass = nullptr;
3068         if (SemaRef.RequireCompleteType(
3069                 Loc, OCIType->getPointeeType(),
3070                 getLangOpts().ObjCAutoRefCount
3071                     ? diag::err_arc_receiver_forward_instance
3072                     : diag::warn_receiver_forward_instance,
3073                 RecRange)) {
3074           if (getLangOpts().ObjCAutoRefCount)
3075             return ExprError();
3076 
3077           forwardClass = OCIType->getInterfaceDecl();
3078           Diag(Receiver ? Receiver->getBeginLoc() : SuperLoc,
3079                diag::note_receiver_is_id);
3080           Method = nullptr;
3081         } else {
3082           Method = ClassDecl->lookupInstanceMethod(Sel);
3083         }
3084 
3085         if (!Method)
3086           // Search protocol qualifiers.
3087           Method = LookupMethodInQualifiedType(Sel, OCIType, true);
3088 
3089         if (!Method) {
3090           // If we have implementations in scope, check "private" methods.
3091           Method = ClassDecl->lookupPrivateMethod(Sel);
3092 
3093           if (!Method && getLangOpts().ObjCAutoRefCount) {
3094             Diag(SelLoc, diag::err_arc_may_not_respond)
3095               << OCIType->getPointeeType() << Sel << RecRange
3096               << SourceRange(SelectorLocs.front(), SelectorLocs.back());
3097             return ExprError();
3098           }
3099 
3100           if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
3101             // If we still haven't found a method, look in the global pool. This
3102             // behavior isn't very desirable, however we need it for GCC
3103             // compatibility. FIXME: should we deviate??
3104             if (OCIType->qual_empty()) {
3105               SmallVector<ObjCMethodDecl*, 4> Methods;
3106               CollectMultipleMethodsInGlobalPool(Sel, Methods,
3107                                                  true/*InstanceFirst*/,
3108                                                  false/*CheckTheOther*/);
3109               if (!Methods.empty()) {
3110                 // We choose the first method as the initial candidate, then try
3111                 // to select a better one.
3112                 Method = Methods[0];
3113 
3114                 if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(
3115                         Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3116                   Method = BestMethod;
3117 
3118                 AreMultipleMethodsInGlobalPool(Sel, Method,
3119                                                SourceRange(LBracLoc, RBracLoc),
3120                                                true/*receiverIdOrClass*/,
3121                                                Methods);
3122               }
3123               if (Method && !forwardClass)
3124                 Diag(SelLoc, diag::warn_maynot_respond)
3125                   << OCIType->getInterfaceDecl()->getIdentifier()
3126                   << Sel << RecRange;
3127             }
3128           }
3129         }
3130         if (Method &&
3131             SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))
3132           return ExprError();
3133       } else {
3134         // Reject other random receiver types (e.g. structs).
3135         Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3136         return ExprError();
3137       }
3138     }
3139   }
3140 
3141   FunctionScopeInfo *DIFunctionScopeInfo =
3142       (Method && Method->getMethodFamily() == OMF_init)
3143           ? SemaRef.getEnclosingFunction()
3144           : nullptr;
3145 
3146   if (Method && Method->isDirectMethod()) {
3147     if (ReceiverType->isObjCIdType() && !isImplicit) {
3148       Diag(Receiver->getExprLoc(),
3149            diag::err_messaging_unqualified_id_with_direct_method);
3150       Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3151           << Method->getDeclName();
3152     }
3153 
3154     // Under ARC, self can't be assigned, and doing a direct call to `self`
3155     // when it's a Class is hence safe.  For other cases, we can't trust `self`
3156     // is what we think it is, so we reject it.
3157     if (ReceiverType->isObjCClassType() && !isImplicit &&
3158         !(Receiver->isObjCSelfExpr() && getLangOpts().ObjCAutoRefCount)) {
3159       {
3160         auto Builder = Diag(Receiver->getExprLoc(),
3161                             diag::err_messaging_class_with_direct_method);
3162         if (Receiver->isObjCSelfExpr()) {
3163           Builder.AddFixItHint(FixItHint::CreateReplacement(
3164               RecRange, Method->getClassInterface()->getName()));
3165         }
3166       }
3167       Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3168           << Method->getDeclName();
3169     }
3170 
3171     if (SuperLoc.isValid()) {
3172       {
3173         auto Builder =
3174             Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3175         if (ReceiverType->isObjCClassType()) {
3176           Builder.AddFixItHint(FixItHint::CreateReplacement(
3177               SuperLoc, Method->getClassInterface()->getName()));
3178         } else {
3179           Builder.AddFixItHint(FixItHint::CreateReplacement(SuperLoc, "self"));
3180         }
3181       }
3182       Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3183           << Method->getDeclName();
3184     }
3185   } else if (ReceiverType->isObjCIdType() && !isImplicit) {
3186     Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);
3187   }
3188 
3189   if (DIFunctionScopeInfo &&
3190       DIFunctionScopeInfo->ObjCIsDesignatedInit &&
3191       (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3192     bool isDesignatedInitChain = false;
3193     if (SuperLoc.isValid()) {
3194       if (const ObjCObjectPointerType *
3195             OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
3196         if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
3197           // Either we know this is a designated initializer or we
3198           // conservatively assume it because we don't know for sure.
3199           if (!ID->declaresOrInheritsDesignatedInitializers() ||
3200               ID->isDesignatedInitializer(Sel)) {
3201             isDesignatedInitChain = true;
3202             DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;
3203           }
3204         }
3205       }
3206     }
3207     if (!isDesignatedInitChain) {
3208       const ObjCMethodDecl *InitMethod = nullptr;
3209       bool isDesignated =
3210           SemaRef.getCurMethodDecl()->isDesignatedInitializerForTheInterface(
3211               &InitMethod);
3212       assert(isDesignated && InitMethod);
3213       (void)isDesignated;
3214       Diag(SelLoc, SuperLoc.isValid() ?
3215              diag::warn_objc_designated_init_non_designated_init_call :
3216              diag::warn_objc_designated_init_non_super_designated_init_call);
3217       Diag(InitMethod->getLocation(),
3218            diag::note_objc_designated_init_marked_here);
3219     }
3220   }
3221 
3222   if (DIFunctionScopeInfo &&
3223       DIFunctionScopeInfo->ObjCIsSecondaryInit &&
3224       (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3225     if (SuperLoc.isValid()) {
3226       Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3227     } else {
3228       DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;
3229     }
3230   }
3231 
3232   // Check the message arguments.
3233   unsigned NumArgs = ArgsIn.size();
3234   Expr **Args = ArgsIn.data();
3235   QualType ReturnType;
3236   ExprValueKind VK = VK_PRValue;
3237   bool ClassMessage = (ReceiverType->isObjCClassType() ||
3238                        ReceiverType->isObjCQualifiedClassType());
3239   if (CheckMessageArgumentTypes(Receiver, ReceiverType,
3240                                 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
3241                                 Method, ClassMessage, SuperLoc.isValid(),
3242                                 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
3243     return ExprError();
3244 
3245   if (Method && !Method->getReturnType()->isVoidType() &&
3246       SemaRef.RequireCompleteType(
3247           LBracLoc, Method->getReturnType(),
3248           diag::err_illegal_message_expr_incomplete_type))
3249     return ExprError();
3250 
3251   // In ARC, forbid the user from sending messages to
3252   // retain/release/autorelease/dealloc/retainCount explicitly.
3253   if (getLangOpts().ObjCAutoRefCount) {
3254     ObjCMethodFamily family =
3255       (Method ? Method->getMethodFamily() : Sel.getMethodFamily());
3256     switch (family) {
3257     case OMF_init:
3258       if (Method)
3259         checkInitMethod(Method, ReceiverType);
3260       break;
3261 
3262     case OMF_None:
3263     case OMF_alloc:
3264     case OMF_copy:
3265     case OMF_finalize:
3266     case OMF_mutableCopy:
3267     case OMF_new:
3268     case OMF_self:
3269     case OMF_initialize:
3270       break;
3271 
3272     case OMF_dealloc:
3273     case OMF_retain:
3274     case OMF_release:
3275     case OMF_autorelease:
3276     case OMF_retainCount:
3277       Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3278         << Sel << RecRange;
3279       break;
3280 
3281     case OMF_performSelector:
3282       if (Method && NumArgs >= 1) {
3283         if (const auto *SelExp =
3284                 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3285           Selector ArgSel = SelExp->getSelector();
3286           ObjCMethodDecl *SelMethod =
3287             LookupInstanceMethodInGlobalPool(ArgSel,
3288                                              SelExp->getSourceRange());
3289           if (!SelMethod)
3290             SelMethod =
3291               LookupFactoryMethodInGlobalPool(ArgSel,
3292                                               SelExp->getSourceRange());
3293           if (SelMethod) {
3294             ObjCMethodFamily SelFamily = SelMethod->getMethodFamily();
3295             switch (SelFamily) {
3296               case OMF_alloc:
3297               case OMF_copy:
3298               case OMF_mutableCopy:
3299               case OMF_new:
3300               case OMF_init:
3301                 // Issue error, unless ns_returns_not_retained.
3302                 if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
3303                   // selector names a +1 method
3304                   Diag(SelLoc,
3305                        diag::err_arc_perform_selector_retains);
3306                   Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3307                     << SelMethod->getDeclName();
3308                 }
3309                 break;
3310               default:
3311                 // +0 call. OK. unless ns_returns_retained.
3312                 if (SelMethod->hasAttr<NSReturnsRetainedAttr>()) {
3313                   // selector names a +1 method
3314                   Diag(SelLoc,
3315                        diag::err_arc_perform_selector_retains);
3316                   Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3317                     << SelMethod->getDeclName();
3318                 }
3319                 break;
3320             }
3321           }
3322         } else {
3323           // error (may leak).
3324           Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3325           Diag(Args[0]->getExprLoc(), diag::note_used_here);
3326         }
3327       }
3328       break;
3329     }
3330   }
3331 
3332   DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs);
3333 
3334   // Construct the appropriate ObjCMessageExpr instance.
3335   ObjCMessageExpr *Result;
3336   if (SuperLoc.isValid())
3337     Result = ObjCMessageExpr::Create(
3338         Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true,
3339         ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
3340         RBracLoc, isImplicit);
3341   else {
3342     Result = ObjCMessageExpr::Create(
3343         Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,
3344         ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3345     if (!isImplicit)
3346       checkCocoaAPI(SemaRef, Result);
3347   }
3348   if (Method) {
3349     bool IsClassObjectCall = ClassMessage;
3350     // 'self' message receivers in class methods should be treated as message
3351     // sends to the class object in order for the semantic checks to be
3352     // performed correctly. Messages to 'super' already count as class messages,
3353     // so they don't need to be handled here.
3354     if (Receiver && isSelfExpr(Receiver)) {
3355       if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
3356         if (OPT->getObjectType()->isObjCClass()) {
3357           if (const auto *CurMeth = SemaRef.getCurMethodDecl()) {
3358             IsClassObjectCall = true;
3359             ReceiverType =
3360                 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3361           }
3362         }
3363       }
3364     }
3365     checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs),
3366                        ReceiverType, IsClassObjectCall);
3367   }
3368 
3369   if (getLangOpts().ObjCAutoRefCount) {
3370     // In ARC, annotate delegate init calls.
3371     if (Result->getMethodFamily() == OMF_init &&
3372         (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3373       // Only consider init calls *directly* in init implementations,
3374       // not within blocks.
3375       ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext);
3376       if (method && method->getMethodFamily() == OMF_init) {
3377         // The implicit assignment to self means we also don't want to
3378         // consume the result.
3379         Result->setDelegateInitCall(true);
3380         return Result;
3381       }
3382     }
3383 
3384     // In ARC, check for message sends which are likely to introduce
3385     // retain cycles.
3386     checkRetainCycles(Result);
3387   }
3388 
3389   if (getLangOpts().ObjCWeak) {
3390     if (!isImplicit && Method) {
3391       if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
3392         bool IsWeak =
3393             Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak;
3394         if (!IsWeak && Sel.isUnarySelector())
3395           IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
3396         if (IsWeak && !SemaRef.isUnevaluatedContext() &&
3397             !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak,
3398                                         LBracLoc))
3399           SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop);
3400       }
3401     }
3402   }
3403 
3404   CheckObjCCircularContainer(Result);
3405 
3406   return SemaRef.MaybeBindToTemporary(Result);
3407 }
3408 
RemoveSelectorFromWarningCache(SemaObjC & S,Expr * Arg)3409 static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg) {
3410   if (ObjCSelectorExpr *OSE =
3411       dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) {
3412     Selector Sel = OSE->getSelector();
3413     SourceLocation Loc = OSE->getAtLoc();
3414     auto Pos = S.ReferencedSelectors.find(Sel);
3415     if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)
3416       S.ReferencedSelectors.erase(Pos);
3417   }
3418 }
3419 
3420 // ActOnInstanceMessage - used for both unary and keyword messages.
3421 // ArgExprs is optional - if it is present, the number of expressions
3422 // is obtained from Sel.getNumArgs().
ActOnInstanceMessage(Scope * S,Expr * Receiver,Selector Sel,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg Args)3423 ExprResult SemaObjC::ActOnInstanceMessage(Scope *S, Expr *Receiver,
3424                                           Selector Sel, SourceLocation LBracLoc,
3425                                           ArrayRef<SourceLocation> SelectorLocs,
3426                                           SourceLocation RBracLoc,
3427                                           MultiExprArg Args) {
3428   ASTContext &Context = getASTContext();
3429   if (!Receiver)
3430     return ExprError();
3431 
3432   // A ParenListExpr can show up while doing error recovery with invalid code.
3433   if (isa<ParenListExpr>(Receiver)) {
3434     ExprResult Result =
3435         SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3436     if (Result.isInvalid()) return ExprError();
3437     Receiver = Result.get();
3438   }
3439 
3440   if (RespondsToSelectorSel.isNull()) {
3441     IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");
3442     RespondsToSelectorSel = Context.Selectors.getUnarySelector(SelectorId);
3443   }
3444   if (Sel == RespondsToSelectorSel)
3445     RemoveSelectorFromWarningCache(*this, Args[0]);
3446 
3447   return BuildInstanceMessage(Receiver, Receiver->getType(),
3448                               /*SuperLoc=*/SourceLocation(), Sel,
3449                               /*Method=*/nullptr, LBracLoc, SelectorLocs,
3450                               RBracLoc, Args);
3451 }
3452 
3453 enum ARCConversionTypeClass {
3454   /// int, void, struct A
3455   ACTC_none,
3456 
3457   /// id, void (^)()
3458   ACTC_retainable,
3459 
3460   /// id*, id***, void (^*)(),
3461   ACTC_indirectRetainable,
3462 
3463   /// void* might be a normal C type, or it might a CF type.
3464   ACTC_voidPtr,
3465 
3466   /// struct A*
3467   ACTC_coreFoundation
3468 };
3469 
isAnyRetainable(ARCConversionTypeClass ACTC)3470 static bool isAnyRetainable(ARCConversionTypeClass ACTC) {
3471   return (ACTC == ACTC_retainable ||
3472           ACTC == ACTC_coreFoundation ||
3473           ACTC == ACTC_voidPtr);
3474 }
3475 
isAnyCLike(ARCConversionTypeClass ACTC)3476 static bool isAnyCLike(ARCConversionTypeClass ACTC) {
3477   return ACTC == ACTC_none ||
3478          ACTC == ACTC_voidPtr ||
3479          ACTC == ACTC_coreFoundation;
3480 }
3481 
classifyTypeForARCConversion(QualType type)3482 static ARCConversionTypeClass classifyTypeForARCConversion(QualType type) {
3483   bool isIndirect = false;
3484 
3485   // Ignore an outermost reference type.
3486   if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
3487     type = ref->getPointeeType();
3488     isIndirect = true;
3489   }
3490 
3491   // Drill through pointers and arrays recursively.
3492   while (true) {
3493     if (const PointerType *ptr = type->getAs<PointerType>()) {
3494       type = ptr->getPointeeType();
3495 
3496       // The first level of pointer may be the innermost pointer on a CF type.
3497       if (!isIndirect) {
3498         if (type->isVoidType()) return ACTC_voidPtr;
3499         if (type->isRecordType()) return ACTC_coreFoundation;
3500       }
3501     } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {
3502       type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3503     } else {
3504       break;
3505     }
3506     isIndirect = true;
3507   }
3508 
3509   if (isIndirect) {
3510     if (type->isObjCARCBridgableType())
3511       return ACTC_indirectRetainable;
3512     return ACTC_none;
3513   }
3514 
3515   if (type->isObjCARCBridgableType())
3516     return ACTC_retainable;
3517 
3518   return ACTC_none;
3519 }
3520 
3521 namespace {
3522   /// A result from the cast checker.
3523   enum ACCResult {
3524     /// Cannot be casted.
3525     ACC_invalid,
3526 
3527     /// Can be safely retained or not retained.
3528     ACC_bottom,
3529 
3530     /// Can be casted at +0.
3531     ACC_plusZero,
3532 
3533     /// Can be casted at +1.
3534     ACC_plusOne
3535   };
merge(ACCResult left,ACCResult right)3536   ACCResult merge(ACCResult left, ACCResult right) {
3537     if (left == right) return left;
3538     if (left == ACC_bottom) return right;
3539     if (right == ACC_bottom) return left;
3540     return ACC_invalid;
3541   }
3542 
3543   /// A checker which white-lists certain expressions whose conversion
3544   /// to or from retainable type would otherwise be forbidden in ARC.
3545   class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {
3546     typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3547 
3548     ASTContext &Context;
3549     ARCConversionTypeClass SourceClass;
3550     ARCConversionTypeClass TargetClass;
3551     bool Diagnose;
3552 
isCFType(QualType type)3553     static bool isCFType(QualType type) {
3554       // Someday this can use ns_bridged.  For now, it has to do this.
3555       return type->isCARCBridgableType();
3556     }
3557 
3558   public:
ARCCastChecker(ASTContext & Context,ARCConversionTypeClass source,ARCConversionTypeClass target,bool diagnose)3559     ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
3560                    ARCConversionTypeClass target, bool diagnose)
3561       : Context(Context), SourceClass(source), TargetClass(target),
3562         Diagnose(diagnose) {}
3563 
3564     using super::Visit;
Visit(Expr * e)3565     ACCResult Visit(Expr *e) {
3566       return super::Visit(e->IgnoreParens());
3567     }
3568 
VisitStmt(Stmt * s)3569     ACCResult VisitStmt(Stmt *s) {
3570       return ACC_invalid;
3571     }
3572 
3573     /// Null pointer constants can be casted however you please.
VisitExpr(Expr * e)3574     ACCResult VisitExpr(Expr *e) {
3575       if (e->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
3576         return ACC_bottom;
3577       return ACC_invalid;
3578     }
3579 
3580     /// Objective-C string literals can be safely casted.
VisitObjCStringLiteral(ObjCStringLiteral * e)3581     ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {
3582       // If we're casting to any retainable type, go ahead.  Global
3583       // strings are immune to retains, so this is bottom.
3584       if (isAnyRetainable(TargetClass)) return ACC_bottom;
3585 
3586       return ACC_invalid;
3587     }
3588 
3589     /// Look through certain implicit and explicit casts.
VisitCastExpr(CastExpr * e)3590     ACCResult VisitCastExpr(CastExpr *e) {
3591       switch (e->getCastKind()) {
3592         case CK_NullToPointer:
3593           return ACC_bottom;
3594 
3595         case CK_NoOp:
3596         case CK_LValueToRValue:
3597         case CK_BitCast:
3598         case CK_CPointerToObjCPointerCast:
3599         case CK_BlockPointerToObjCPointerCast:
3600         case CK_AnyPointerToBlockPointerCast:
3601           return Visit(e->getSubExpr());
3602 
3603         default:
3604           return ACC_invalid;
3605       }
3606     }
3607 
3608     /// Look through unary extension.
VisitUnaryExtension(UnaryOperator * e)3609     ACCResult VisitUnaryExtension(UnaryOperator *e) {
3610       return Visit(e->getSubExpr());
3611     }
3612 
3613     /// Ignore the LHS of a comma operator.
VisitBinComma(BinaryOperator * e)3614     ACCResult VisitBinComma(BinaryOperator *e) {
3615       return Visit(e->getRHS());
3616     }
3617 
3618     /// Conditional operators are okay if both sides are okay.
VisitConditionalOperator(ConditionalOperator * e)3619     ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3620       ACCResult left = Visit(e->getTrueExpr());
3621       if (left == ACC_invalid) return ACC_invalid;
3622       return merge(left, Visit(e->getFalseExpr()));
3623     }
3624 
3625     /// Look through pseudo-objects.
VisitPseudoObjectExpr(PseudoObjectExpr * e)3626     ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3627       // If we're getting here, we should always have a result.
3628       return Visit(e->getResultExpr());
3629     }
3630 
3631     /// Statement expressions are okay if their result expression is okay.
VisitStmtExpr(StmtExpr * e)3632     ACCResult VisitStmtExpr(StmtExpr *e) {
3633       return Visit(e->getSubStmt()->body_back());
3634     }
3635 
3636     /// Some declaration references are okay.
VisitDeclRefExpr(DeclRefExpr * e)3637     ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3638       VarDecl *var = dyn_cast<VarDecl>(e->getDecl());
3639       // References to global constants are okay.
3640       if (isAnyRetainable(TargetClass) &&
3641           isAnyRetainable(SourceClass) &&
3642           var &&
3643           !var->hasDefinition(Context) &&
3644           var->getType().isConstQualified()) {
3645 
3646         // In system headers, they can also be assumed to be immune to retains.
3647         // These are things like 'kCFStringTransformToLatin'.
3648         if (Context.getSourceManager().isInSystemHeader(var->getLocation()))
3649           return ACC_bottom;
3650 
3651         return ACC_plusZero;
3652       }
3653 
3654       // Nothing else.
3655       return ACC_invalid;
3656     }
3657 
3658     /// Some calls are okay.
VisitCallExpr(CallExpr * e)3659     ACCResult VisitCallExpr(CallExpr *e) {
3660       if (FunctionDecl *fn = e->getDirectCallee())
3661         if (ACCResult result = checkCallToFunction(fn))
3662           return result;
3663 
3664       return super::VisitCallExpr(e);
3665     }
3666 
checkCallToFunction(FunctionDecl * fn)3667     ACCResult checkCallToFunction(FunctionDecl *fn) {
3668       // Require a CF*Ref return type.
3669       if (!isCFType(fn->getReturnType()))
3670         return ACC_invalid;
3671 
3672       if (!isAnyRetainable(TargetClass))
3673         return ACC_invalid;
3674 
3675       // Honor an explicit 'not retained' attribute.
3676       if (fn->hasAttr<CFReturnsNotRetainedAttr>())
3677         return ACC_plusZero;
3678 
3679       // Honor an explicit 'retained' attribute, except that for
3680       // now we're not going to permit implicit handling of +1 results,
3681       // because it's a bit frightening.
3682       if (fn->hasAttr<CFReturnsRetainedAttr>())
3683         return Diagnose ? ACC_plusOne
3684                         : ACC_invalid; // ACC_plusOne if we start accepting this
3685 
3686       // Recognize this specific builtin function, which is used by CFSTR.
3687       unsigned builtinID = fn->getBuiltinID();
3688       if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3689         return ACC_bottom;
3690 
3691       // Otherwise, don't do anything implicit with an unaudited function.
3692       if (!fn->hasAttr<CFAuditedTransferAttr>())
3693         return ACC_invalid;
3694 
3695       // Otherwise, it's +0 unless it follows the create convention.
3696       if (ento::coreFoundation::followsCreateRule(fn))
3697         return Diagnose ? ACC_plusOne
3698                         : ACC_invalid; // ACC_plusOne if we start accepting this
3699 
3700       return ACC_plusZero;
3701     }
3702 
VisitObjCMessageExpr(ObjCMessageExpr * e)3703     ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3704       return checkCallToMethod(e->getMethodDecl());
3705     }
3706 
VisitObjCPropertyRefExpr(ObjCPropertyRefExpr * e)3707     ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3708       ObjCMethodDecl *method;
3709       if (e->isExplicitProperty())
3710         method = e->getExplicitProperty()->getGetterMethodDecl();
3711       else
3712         method = e->getImplicitPropertyGetter();
3713       return checkCallToMethod(method);
3714     }
3715 
checkCallToMethod(ObjCMethodDecl * method)3716     ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3717       if (!method) return ACC_invalid;
3718 
3719       // Check for message sends to functions returning CF types.  We
3720       // just obey the Cocoa conventions with these, even though the
3721       // return type is CF.
3722       if (!isAnyRetainable(TargetClass) || !isCFType(method->getReturnType()))
3723         return ACC_invalid;
3724 
3725       // If the method is explicitly marked not-retained, it's +0.
3726       if (method->hasAttr<CFReturnsNotRetainedAttr>())
3727         return ACC_plusZero;
3728 
3729       // If the method is explicitly marked as returning retained, or its
3730       // selector follows a +1 Cocoa convention, treat it as +1.
3731       if (method->hasAttr<CFReturnsRetainedAttr>())
3732         return ACC_plusOne;
3733 
3734       switch (method->getSelector().getMethodFamily()) {
3735       case OMF_alloc:
3736       case OMF_copy:
3737       case OMF_mutableCopy:
3738       case OMF_new:
3739         return ACC_plusOne;
3740 
3741       default:
3742         // Otherwise, treat it as +0.
3743         return ACC_plusZero;
3744       }
3745     }
3746   };
3747 } // end anonymous namespace
3748 
isKnownName(StringRef name)3749 bool SemaObjC::isKnownName(StringRef name) {
3750   ASTContext &Context = getASTContext();
3751   if (name.empty())
3752     return false;
3753   LookupResult R(SemaRef, &Context.Idents.get(name), SourceLocation(),
3754                  Sema::LookupOrdinaryName);
3755   return SemaRef.LookupName(R, SemaRef.TUScope, false);
3756 }
3757 
3758 template <typename DiagBuilderT>
addFixitForObjCARCConversion(Sema & S,DiagBuilderT & DiagB,CheckedConversionKind CCK,SourceLocation afterLParen,QualType castType,Expr * castExpr,Expr * realCast,const char * bridgeKeyword,const char * CFBridgeName)3759 static void addFixitForObjCARCConversion(
3760     Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK,
3761     SourceLocation afterLParen, QualType castType, Expr *castExpr,
3762     Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {
3763   // We handle C-style and implicit casts here.
3764   switch (CCK) {
3765   case CheckedConversionKind::Implicit:
3766   case CheckedConversionKind::ForBuiltinOverloadedOp:
3767   case CheckedConversionKind::CStyleCast:
3768   case CheckedConversionKind::OtherCast:
3769     break;
3770   case CheckedConversionKind::FunctionalCast:
3771     return;
3772   }
3773 
3774   if (CFBridgeName) {
3775     if (CCK == CheckedConversionKind::OtherCast) {
3776       if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3777         SourceRange range(NCE->getOperatorLoc(),
3778                           NCE->getAngleBrackets().getEnd());
3779         SmallString<32> BridgeCall;
3780 
3781         SourceManager &SM = S.getSourceManager();
3782         char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3783         if (Lexer::isAsciiIdentifierContinueChar(PrevChar, S.getLangOpts()))
3784           BridgeCall += ' ';
3785 
3786         BridgeCall += CFBridgeName;
3787         DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall));
3788       }
3789       return;
3790     }
3791     Expr *castedE = castExpr;
3792     if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))
3793       castedE = CCE->getSubExpr();
3794     castedE = castedE->IgnoreImpCasts();
3795     SourceRange range = castedE->getSourceRange();
3796 
3797     SmallString<32> BridgeCall;
3798 
3799     SourceManager &SM = S.getSourceManager();
3800     char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3801     if (Lexer::isAsciiIdentifierContinueChar(PrevChar, S.getLangOpts()))
3802       BridgeCall += ' ';
3803 
3804     BridgeCall += CFBridgeName;
3805 
3806     if (isa<ParenExpr>(castedE)) {
3807       DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3808                          BridgeCall));
3809     } else {
3810       BridgeCall += '(';
3811       DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3812                                                     BridgeCall));
3813       DiagB.AddFixItHint(FixItHint::CreateInsertion(
3814                                        S.getLocForEndOfToken(range.getEnd()),
3815                                        ")"));
3816     }
3817     return;
3818   }
3819 
3820   if (CCK == CheckedConversionKind::CStyleCast) {
3821     DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
3822   } else if (CCK == CheckedConversionKind::OtherCast) {
3823     if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3824       std::string castCode = "(";
3825       castCode += bridgeKeyword;
3826       castCode += castType.getAsString();
3827       castCode += ")";
3828       SourceRange Range(NCE->getOperatorLoc(),
3829                         NCE->getAngleBrackets().getEnd());
3830       DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode));
3831     }
3832   } else {
3833     std::string castCode = "(";
3834     castCode += bridgeKeyword;
3835     castCode += castType.getAsString();
3836     castCode += ")";
3837     Expr *castedE = castExpr->IgnoreImpCasts();
3838     SourceRange range = castedE->getSourceRange();
3839     if (isa<ParenExpr>(castedE)) {
3840       DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3841                          castCode));
3842     } else {
3843       castCode += "(";
3844       DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3845                                                     castCode));
3846       DiagB.AddFixItHint(FixItHint::CreateInsertion(
3847                                        S.getLocForEndOfToken(range.getEnd()),
3848                                        ")"));
3849     }
3850   }
3851 }
3852 
3853 template <typename T>
getObjCBridgeAttr(const TypedefType * TD)3854 static inline T *getObjCBridgeAttr(const TypedefType *TD) {
3855   TypedefNameDecl *TDNDecl = TD->getDecl();
3856   QualType QT = TDNDecl->getUnderlyingType();
3857   if (QT->isPointerType()) {
3858     QT = QT->getPointeeType();
3859     if (const RecordType *RT = QT->getAs<RecordType>()) {
3860       for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
3861         if (auto *attr = Redecl->getAttr<T>())
3862           return attr;
3863       }
3864     }
3865   }
3866   return nullptr;
3867 }
3868 
ObjCBridgeRelatedAttrFromType(QualType T,TypedefNameDecl * & TDNDecl)3869 static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
3870                                                             TypedefNameDecl *&TDNDecl) {
3871   while (const auto *TD = T->getAs<TypedefType>()) {
3872     TDNDecl = TD->getDecl();
3873     if (ObjCBridgeRelatedAttr *ObjCBAttr =
3874         getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD))
3875       return ObjCBAttr;
3876     T = TDNDecl->getUnderlyingType();
3877   }
3878   return nullptr;
3879 }
3880 
diagnoseObjCARCConversion(Sema & S,SourceRange castRange,QualType castType,ARCConversionTypeClass castACTC,Expr * castExpr,Expr * realCast,ARCConversionTypeClass exprACTC,CheckedConversionKind CCK)3881 static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
3882                                       QualType castType,
3883                                       ARCConversionTypeClass castACTC,
3884                                       Expr *castExpr, Expr *realCast,
3885                                       ARCConversionTypeClass exprACTC,
3886                                       CheckedConversionKind CCK) {
3887   SourceLocation loc =
3888     (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());
3889 
3890   if (S.makeUnavailableInSystemHeader(loc,
3891                                  UnavailableAttr::IR_ARCForbiddenConversion))
3892     return;
3893 
3894   QualType castExprType = castExpr->getType();
3895   // Defer emitting a diagnostic for bridge-related casts; that will be
3896   // handled by CheckObjCBridgeRelatedConversions.
3897   TypedefNameDecl *TDNDecl = nullptr;
3898   if ((castACTC == ACTC_coreFoundation &&  exprACTC == ACTC_retainable &&
3899        ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
3900       (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&
3901        ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))
3902     return;
3903 
3904   unsigned srcKind = 0;
3905   switch (exprACTC) {
3906   case ACTC_none:
3907   case ACTC_coreFoundation:
3908   case ACTC_voidPtr:
3909     srcKind = (castExprType->isPointerType() ? 1 : 0);
3910     break;
3911   case ACTC_retainable:
3912     srcKind = (castExprType->isBlockPointerType() ? 2 : 3);
3913     break;
3914   case ACTC_indirectRetainable:
3915     srcKind = 4;
3916     break;
3917   }
3918 
3919   // Check whether this could be fixed with a bridge cast.
3920   SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin());
3921   SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;
3922 
3923   unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;
3924 
3925   // Bridge from an ARC type to a CF type.
3926   if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {
3927 
3928     S.Diag(loc, diag::err_arc_cast_requires_bridge)
3929       << convKindForDiag
3930       << 2 // of C pointer type
3931       << castExprType
3932       << unsigned(castType->isBlockPointerType()) // to ObjC|block type
3933       << castType
3934       << castRange
3935       << castExpr->getSourceRange();
3936     bool br = S.ObjC().isKnownName("CFBridgingRelease");
3937     ACCResult CreateRule =
3938       ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3939     assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3940     if (CreateRule != ACC_plusOne)
3941     {
3942       auto DiagB = (CCK != CheckedConversionKind::OtherCast)
3943                        ? S.Diag(noteLoc, diag::note_arc_bridge)
3944                        : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3945 
3946       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3947                                    castType, castExpr, realCast, "__bridge ",
3948                                    nullptr);
3949     }
3950     if (CreateRule != ACC_plusZero)
3951     {
3952       auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)
3953                        ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
3954                              << castExprType
3955                        : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3956                                 diag::note_arc_bridge_transfer)
3957                              << castExprType << br;
3958 
3959       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3960                                    castType, castExpr, realCast, "__bridge_transfer ",
3961                                    br ? "CFBridgingRelease" : nullptr);
3962     }
3963 
3964     return;
3965   }
3966 
3967   // Bridge from a CF type to an ARC type.
3968   if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
3969     bool br = S.ObjC().isKnownName("CFBridgingRetain");
3970     S.Diag(loc, diag::err_arc_cast_requires_bridge)
3971       << convKindForDiag
3972       << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
3973       << castExprType
3974       << 2 // to C pointer type
3975       << castType
3976       << castRange
3977       << castExpr->getSourceRange();
3978     ACCResult CreateRule =
3979       ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3980     assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3981     if (CreateRule != ACC_plusOne)
3982     {
3983       auto DiagB = (CCK != CheckedConversionKind::OtherCast)
3984                        ? S.Diag(noteLoc, diag::note_arc_bridge)
3985                        : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3986       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3987                                    castType, castExpr, realCast, "__bridge ",
3988                                    nullptr);
3989     }
3990     if (CreateRule != ACC_plusZero)
3991     {
3992       auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)
3993                        ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
3994                              << castType
3995                        : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3996                                 diag::note_arc_bridge_retained)
3997                              << castType << br;
3998 
3999       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
4000                                    castType, castExpr, realCast, "__bridge_retained ",
4001                                    br ? "CFBridgingRetain" : nullptr);
4002     }
4003 
4004     return;
4005   }
4006 
4007   S.Diag(loc, diag::err_arc_mismatched_cast)
4008     << !convKindForDiag
4009     << srcKind << castExprType << castType
4010     << castRange << castExpr->getSourceRange();
4011 }
4012 
4013 template <typename TB>
CheckObjCBridgeNSCast(Sema & S,QualType castType,Expr * castExpr,bool & HadTheAttribute,bool warn)4014 static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
4015                                   bool &HadTheAttribute, bool warn) {
4016   QualType T = castExpr->getType();
4017   HadTheAttribute = false;
4018   while (const auto *TD = T->getAs<TypedefType>()) {
4019     TypedefNameDecl *TDNDecl = TD->getDecl();
4020     if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4021       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4022         HadTheAttribute = true;
4023         if (Parm->isStr("id"))
4024           return true;
4025 
4026         // Check for an existing type with this name.
4027         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
4028                        Sema::LookupOrdinaryName);
4029         if (S.LookupName(R, S.TUScope)) {
4030           NamedDecl *Target = R.getFoundDecl();
4031           if (Target && isa<ObjCInterfaceDecl>(Target)) {
4032             ObjCInterfaceDecl *ExprClass = cast<ObjCInterfaceDecl>(Target);
4033             if (const ObjCObjectPointerType *InterfacePointerType =
4034                   castType->getAsObjCInterfacePointerType()) {
4035               ObjCInterfaceDecl *CastClass
4036                 = InterfacePointerType->getObjectType()->getInterface();
4037               if ((CastClass == ExprClass) ||
4038                   (CastClass && CastClass->isSuperClassOf(ExprClass)))
4039                 return true;
4040               if (warn)
4041                 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4042                     << T << Target->getName() << castType->getPointeeType();
4043               return false;
4044             } else if (castType->isObjCIdType() ||
4045                        (S.Context.ObjCObjectAdoptsQTypeProtocols(
4046                           castType, ExprClass)))
4047               // ok to cast to 'id'.
4048               // casting to id<p-list> is ok if bridge type adopts all of
4049               // p-list protocols.
4050               return true;
4051             else {
4052               if (warn) {
4053                 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4054                     << T << Target->getName() << castType;
4055                 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4056                 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4057               }
4058               return false;
4059            }
4060           }
4061         } else if (!castType->isObjCIdType()) {
4062           S.Diag(castExpr->getBeginLoc(),
4063                  diag::err_objc_cf_bridged_not_interface)
4064               << castExpr->getType() << Parm;
4065           S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4066         }
4067         return true;
4068       }
4069       return false;
4070     }
4071     T = TDNDecl->getUnderlyingType();
4072   }
4073   return true;
4074 }
4075 
4076 template <typename TB>
CheckObjCBridgeCFCast(Sema & S,QualType castType,Expr * castExpr,bool & HadTheAttribute,bool warn)4077 static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
4078                                   bool &HadTheAttribute, bool warn) {
4079   QualType T = castType;
4080   HadTheAttribute = false;
4081   while (const auto *TD = T->getAs<TypedefType>()) {
4082     TypedefNameDecl *TDNDecl = TD->getDecl();
4083     if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4084       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4085         HadTheAttribute = true;
4086         if (Parm->isStr("id"))
4087           return true;
4088 
4089         NamedDecl *Target = nullptr;
4090         // Check for an existing type with this name.
4091         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
4092                        Sema::LookupOrdinaryName);
4093         if (S.LookupName(R, S.TUScope)) {
4094           Target = R.getFoundDecl();
4095           if (Target && isa<ObjCInterfaceDecl>(Target)) {
4096             ObjCInterfaceDecl *CastClass = cast<ObjCInterfaceDecl>(Target);
4097             if (const ObjCObjectPointerType *InterfacePointerType =
4098                   castExpr->getType()->getAsObjCInterfacePointerType()) {
4099               ObjCInterfaceDecl *ExprClass
4100                 = InterfacePointerType->getObjectType()->getInterface();
4101               if ((CastClass == ExprClass) ||
4102                   (ExprClass && CastClass->isSuperClassOf(ExprClass)))
4103                 return true;
4104               if (warn) {
4105                 S.Diag(castExpr->getBeginLoc(),
4106                        diag::warn_objc_invalid_bridge_to_cf)
4107                     << castExpr->getType()->getPointeeType() << T;
4108                 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4109               }
4110               return false;
4111             } else if (castExpr->getType()->isObjCIdType() ||
4112                        (S.Context.QIdProtocolsAdoptObjCObjectProtocols(
4113                           castExpr->getType(), CastClass)))
4114               // ok to cast an 'id' expression to a CFtype.
4115               // ok to cast an 'id<plist>' expression to CFtype provided plist
4116               // adopts all of CFtype's ObjetiveC's class plist.
4117               return true;
4118             else {
4119               if (warn) {
4120                 S.Diag(castExpr->getBeginLoc(),
4121                        diag::warn_objc_invalid_bridge_to_cf)
4122                     << castExpr->getType() << castType;
4123                 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4124                 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4125               }
4126               return false;
4127             }
4128           }
4129         }
4130         S.Diag(castExpr->getBeginLoc(),
4131                diag::err_objc_ns_bridged_invalid_cfobject)
4132             << castExpr->getType() << castType;
4133         S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4134         if (Target)
4135           S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4136         return true;
4137       }
4138       return false;
4139     }
4140     T = TDNDecl->getUnderlyingType();
4141   }
4142   return true;
4143 }
4144 
CheckTollFreeBridgeCast(QualType castType,Expr * castExpr)4145 void SemaObjC::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
4146   if (!getLangOpts().ObjC)
4147     return;
4148   // warn in presence of __bridge casting to or from a toll free bridge cast.
4149   ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
4150   ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
4151   if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
4152     bool HasObjCBridgeAttr;
4153     bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast<ObjCBridgeAttr>(
4154         SemaRef, castType, castExpr, HasObjCBridgeAttr, false);
4155     if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4156       return;
4157     bool HasObjCBridgeMutableAttr;
4158     bool ObjCBridgeMutableAttrWillNotWarn =
4159         CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(
4160             SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4161     if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4162       return;
4163 
4164     if (HasObjCBridgeAttr)
4165       CheckObjCBridgeNSCast<ObjCBridgeAttr>(SemaRef, castType, castExpr,
4166                                             HasObjCBridgeAttr, true);
4167     else if (HasObjCBridgeMutableAttr)
4168       CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(
4169           SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4170   }
4171   else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
4172     bool HasObjCBridgeAttr;
4173     bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast<ObjCBridgeAttr>(
4174         SemaRef, castType, castExpr, HasObjCBridgeAttr, false);
4175     if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4176       return;
4177     bool HasObjCBridgeMutableAttr;
4178     bool ObjCBridgeMutableAttrWillNotWarn =
4179         CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(
4180             SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4181     if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4182       return;
4183 
4184     if (HasObjCBridgeAttr)
4185       CheckObjCBridgeCFCast<ObjCBridgeAttr>(SemaRef, castType, castExpr,
4186                                             HasObjCBridgeAttr, true);
4187     else if (HasObjCBridgeMutableAttr)
4188       CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(
4189           SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4190   }
4191 }
4192 
CheckObjCBridgeRelatedCast(QualType castType,Expr * castExpr)4193 void SemaObjC::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {
4194   QualType SrcType = castExpr->getType();
4195   if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
4196     if (PRE->isExplicitProperty()) {
4197       if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
4198         SrcType = PDecl->getType();
4199     }
4200     else if (PRE->isImplicitProperty()) {
4201       if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
4202         SrcType = Getter->getReturnType();
4203     }
4204   }
4205 
4206   ARCConversionTypeClass srcExprACTC = classifyTypeForARCConversion(SrcType);
4207   ARCConversionTypeClass castExprACTC = classifyTypeForARCConversion(castType);
4208   if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
4209     return;
4210   CheckObjCBridgeRelatedConversions(castExpr->getBeginLoc(), castType, SrcType,
4211                                     castExpr);
4212 }
4213 
CheckTollFreeBridgeStaticCast(QualType castType,Expr * castExpr,CastKind & Kind)4214 bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
4215                                              CastKind &Kind) {
4216   if (!getLangOpts().ObjC)
4217     return false;
4218   ARCConversionTypeClass exprACTC =
4219     classifyTypeForARCConversion(castExpr->getType());
4220   ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
4221   if ((castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) ||
4222       (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable)) {
4223     CheckTollFreeBridgeCast(castType, castExpr);
4224     Kind = (castACTC == ACTC_coreFoundation) ? CK_BitCast
4225                                              : CK_CPointerToObjCPointerCast;
4226     return true;
4227   }
4228   return false;
4229 }
4230 
checkObjCBridgeRelatedComponents(SourceLocation Loc,QualType DestType,QualType SrcType,ObjCInterfaceDecl * & RelatedClass,ObjCMethodDecl * & ClassMethod,ObjCMethodDecl * & InstanceMethod,TypedefNameDecl * & TDNDecl,bool CfToNs,bool Diagnose)4231 bool SemaObjC::checkObjCBridgeRelatedComponents(
4232     SourceLocation Loc, QualType DestType, QualType SrcType,
4233     ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod,
4234     ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs,
4235     bool Diagnose) {
4236   ASTContext &Context = getASTContext();
4237   QualType T = CfToNs ? SrcType : DestType;
4238   ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
4239   if (!ObjCBAttr)
4240     return false;
4241 
4242   IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
4243   IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
4244   IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
4245   if (!RCId)
4246     return false;
4247   NamedDecl *Target = nullptr;
4248   // Check for an existing type with this name.
4249   LookupResult R(SemaRef, DeclarationName(RCId), SourceLocation(),
4250                  Sema::LookupOrdinaryName);
4251   if (!SemaRef.LookupName(R, SemaRef.TUScope)) {
4252     if (Diagnose) {
4253       Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4254             << SrcType << DestType;
4255       Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4256     }
4257     return false;
4258   }
4259   Target = R.getFoundDecl();
4260   if (Target && isa<ObjCInterfaceDecl>(Target))
4261     RelatedClass = cast<ObjCInterfaceDecl>(Target);
4262   else {
4263     if (Diagnose) {
4264       Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4265             << SrcType << DestType;
4266       Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4267       if (Target)
4268         Diag(Target->getBeginLoc(), diag::note_declared_at);
4269     }
4270     return false;
4271   }
4272 
4273   // Check for an existing class method with the given selector name.
4274   if (CfToNs && CMId) {
4275     Selector Sel = Context.Selectors.getUnarySelector(CMId);
4276     ClassMethod = RelatedClass->lookupMethod(Sel, false);
4277     if (!ClassMethod) {
4278       if (Diagnose) {
4279         Diag(Loc, diag::err_objc_bridged_related_known_method)
4280               << SrcType << DestType << Sel << false;
4281         Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4282       }
4283       return false;
4284     }
4285   }
4286 
4287   // Check for an existing instance method with the given selector name.
4288   if (!CfToNs && IMId) {
4289     Selector Sel = Context.Selectors.getNullarySelector(IMId);
4290     InstanceMethod = RelatedClass->lookupMethod(Sel, true);
4291     if (!InstanceMethod) {
4292       if (Diagnose) {
4293         Diag(Loc, diag::err_objc_bridged_related_known_method)
4294               << SrcType << DestType << Sel << true;
4295         Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4296       }
4297       return false;
4298     }
4299   }
4300   return true;
4301 }
4302 
CheckObjCBridgeRelatedConversions(SourceLocation Loc,QualType DestType,QualType SrcType,Expr * & SrcExpr,bool Diagnose)4303 bool SemaObjC::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
4304                                                  QualType DestType,
4305                                                  QualType SrcType,
4306                                                  Expr *&SrcExpr,
4307                                                  bool Diagnose) {
4308   ASTContext &Context = getASTContext();
4309   ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
4310   ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
4311   bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
4312   bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);
4313   if (!CfToNs && !NsToCf)
4314     return false;
4315 
4316   ObjCInterfaceDecl *RelatedClass;
4317   ObjCMethodDecl *ClassMethod = nullptr;
4318   ObjCMethodDecl *InstanceMethod = nullptr;
4319   TypedefNameDecl *TDNDecl = nullptr;
4320   if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
4321                                         ClassMethod, InstanceMethod, TDNDecl,
4322                                         CfToNs, Diagnose))
4323     return false;
4324 
4325   if (CfToNs) {
4326     // Implicit conversion from CF to ObjC object is needed.
4327     if (ClassMethod) {
4328       if (Diagnose) {
4329         std::string ExpressionString = "[";
4330         ExpressionString += RelatedClass->getNameAsString();
4331         ExpressionString += " ";
4332         ExpressionString += ClassMethod->getSelector().getAsString();
4333         SourceLocation SrcExprEndLoc =
4334             SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc());
4335         // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
4336         Diag(Loc, diag::err_objc_bridged_related_known_method)
4337             << SrcType << DestType << ClassMethod->getSelector() << false
4338             << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(),
4339                                           ExpressionString)
4340             << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
4341         Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4342         Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4343 
4344         QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4345         // Argument.
4346         Expr *args[] = { SrcExpr };
4347         ExprResult msg = BuildClassMessageImplicit(receiverType, false,
4348                                       ClassMethod->getLocation(),
4349                                       ClassMethod->getSelector(), ClassMethod,
4350                                       MultiExprArg(args, 1));
4351         SrcExpr = msg.get();
4352       }
4353       return true;
4354     }
4355   }
4356   else {
4357     // Implicit conversion from ObjC type to CF object is needed.
4358     if (InstanceMethod) {
4359       if (Diagnose) {
4360         std::string ExpressionString;
4361         SourceLocation SrcExprEndLoc =
4362             SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc());
4363         if (InstanceMethod->isPropertyAccessor())
4364           if (const ObjCPropertyDecl *PDecl =
4365                   InstanceMethod->findPropertyDecl()) {
4366             // fixit: ObjectExpr.propertyname when it is  aproperty accessor.
4367             ExpressionString = ".";
4368             ExpressionString += PDecl->getNameAsString();
4369             Diag(Loc, diag::err_objc_bridged_related_known_method)
4370                 << SrcType << DestType << InstanceMethod->getSelector() << true
4371                 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4372           }
4373         if (ExpressionString.empty()) {
4374           // Provide a fixit: [ObjectExpr InstanceMethod]
4375           ExpressionString = " ";
4376           ExpressionString += InstanceMethod->getSelector().getAsString();
4377           ExpressionString += "]";
4378 
4379           Diag(Loc, diag::err_objc_bridged_related_known_method)
4380               << SrcType << DestType << InstanceMethod->getSelector() << true
4381               << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "[")
4382               << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4383         }
4384         Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4385         Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4386 
4387         ExprResult msg = BuildInstanceMessageImplicit(
4388             SrcExpr, SrcType, InstanceMethod->getLocation(),
4389             InstanceMethod->getSelector(), InstanceMethod, std::nullopt);
4390         SrcExpr = msg.get();
4391       }
4392       return true;
4393     }
4394   }
4395   return false;
4396 }
4397 
4398 SemaObjC::ARCConversionResult
CheckObjCConversion(SourceRange castRange,QualType castType,Expr * & castExpr,CheckedConversionKind CCK,bool Diagnose,bool DiagnoseCFAudited,BinaryOperatorKind Opc)4399 SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType,
4400                               Expr *&castExpr, CheckedConversionKind CCK,
4401                               bool Diagnose, bool DiagnoseCFAudited,
4402                               BinaryOperatorKind Opc) {
4403   ASTContext &Context = getASTContext();
4404   QualType castExprType = castExpr->getType();
4405 
4406   // For the purposes of the classification, we assume reference types
4407   // will bind to temporaries.
4408   QualType effCastType = castType;
4409   if (const ReferenceType *ref = castType->getAs<ReferenceType>())
4410     effCastType = ref->getPointeeType();
4411 
4412   ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);
4413   ARCConversionTypeClass castACTC = classifyTypeForARCConversion(effCastType);
4414   if (exprACTC == castACTC) {
4415     // Check for viability and report error if casting an rvalue to a
4416     // life-time qualifier.
4417     if (castACTC == ACTC_retainable &&
4418         (CCK == CheckedConversionKind::CStyleCast ||
4419          CCK == CheckedConversionKind::OtherCast) &&
4420         castType != castExprType) {
4421       const Type *DT = castType.getTypePtr();
4422       QualType QDT = castType;
4423       // We desugar some types but not others. We ignore those
4424       // that cannot happen in a cast; i.e. auto, and those which
4425       // should not be de-sugared; i.e typedef.
4426       if (const ParenType *PT = dyn_cast<ParenType>(DT))
4427         QDT = PT->desugar();
4428       else if (const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4429         QDT = TP->desugar();
4430       else if (const AttributedType *AT = dyn_cast<AttributedType>(DT))
4431         QDT = AT->desugar();
4432       if (QDT != castType &&
4433           QDT.getObjCLifetime() !=  Qualifiers::OCL_None) {
4434         if (Diagnose) {
4435           SourceLocation loc = (castRange.isValid() ? castRange.getBegin()
4436                                                     : castExpr->getExprLoc());
4437           Diag(loc, diag::err_arc_nolifetime_behavior);
4438         }
4439         return ACR_error;
4440       }
4441     }
4442     return ACR_okay;
4443   }
4444 
4445   // The life-time qualifier cast check above is all we need for ObjCWeak.
4446   // ObjCAutoRefCount has more restrictions on what is legal.
4447   if (!getLangOpts().ObjCAutoRefCount)
4448     return ACR_okay;
4449 
4450   if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;
4451 
4452   // Allow all of these types to be cast to integer types (but not
4453   // vice-versa).
4454   if (castACTC == ACTC_none && castType->isIntegralType(Context))
4455     return ACR_okay;
4456 
4457   // Allow casts between pointers to lifetime types (e.g., __strong id*)
4458   // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
4459   // must be explicit.
4460   // Allow conversions between pointers to lifetime types and coreFoundation
4461   // pointers too, but only when the conversions are explicit.
4462   if (exprACTC == ACTC_indirectRetainable &&
4463       (castACTC == ACTC_voidPtr ||
4464        (castACTC == ACTC_coreFoundation && SemaRef.isCast(CCK))))
4465     return ACR_okay;
4466   if (castACTC == ACTC_indirectRetainable &&
4467       (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&
4468       SemaRef.isCast(CCK))
4469     return ACR_okay;
4470 
4471   switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
4472   // For invalid casts, fall through.
4473   case ACC_invalid:
4474     break;
4475 
4476   // Do nothing for both bottom and +0.
4477   case ACC_bottom:
4478   case ACC_plusZero:
4479     return ACR_okay;
4480 
4481   // If the result is +1, consume it here.
4482   case ACC_plusOne:
4483     castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
4484                                         CK_ARCConsumeObject, castExpr, nullptr,
4485                                         VK_PRValue, FPOptionsOverride());
4486     SemaRef.Cleanup.setExprNeedsCleanups(true);
4487     return ACR_okay;
4488   }
4489 
4490   // If this is a non-implicit cast from id or block type to a
4491   // CoreFoundation type, delay complaining in case the cast is used
4492   // in an acceptable context.
4493   if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) &&
4494       SemaRef.isCast(CCK))
4495     return ACR_unbridged;
4496 
4497   // Issue a diagnostic about a missing @-sign when implicit casting a cstring
4498   // to 'NSString *', instead of falling through to report a "bridge cast"
4499   // diagnostic.
4500   if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
4501       CheckConversionToObjCLiteral(castType, castExpr, Diagnose))
4502     return ACR_error;
4503 
4504   // Do not issue "bridge cast" diagnostic when implicit casting
4505   // a retainable object to a CF type parameter belonging to an audited
4506   // CF API function. Let caller issue a normal type mismatched diagnostic
4507   // instead.
4508   if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
4509        castACTC != ACTC_coreFoundation) &&
4510       !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
4511         (Opc == BO_NE || Opc == BO_EQ))) {
4512     if (Diagnose)
4513       diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC,
4514                                 castExpr, castExpr, exprACTC, CCK);
4515     return ACR_error;
4516   }
4517   return ACR_okay;
4518 }
4519 
4520 /// Given that we saw an expression with the ARCUnbridgedCastTy
4521 /// placeholder type, complain bitterly.
diagnoseARCUnbridgedCast(Expr * e)4522 void SemaObjC::diagnoseARCUnbridgedCast(Expr *e) {
4523   // We expect the spurious ImplicitCastExpr to already have been stripped.
4524   assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4525   CastExpr *realCast = cast<CastExpr>(e->IgnoreParens());
4526 
4527   SourceRange castRange;
4528   QualType castType;
4529   CheckedConversionKind CCK;
4530 
4531   if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {
4532     castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());
4533     castType = cast->getTypeAsWritten();
4534     CCK = CheckedConversionKind::CStyleCast;
4535   } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {
4536     castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4537     castType = cast->getTypeAsWritten();
4538     CCK = CheckedConversionKind::OtherCast;
4539   } else {
4540     llvm_unreachable("Unexpected ImplicitCastExpr");
4541   }
4542 
4543   ARCConversionTypeClass castACTC =
4544     classifyTypeForARCConversion(castType.getNonReferenceType());
4545 
4546   Expr *castExpr = realCast->getSubExpr();
4547   assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable);
4548 
4549   diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr,
4550                             realCast, ACTC_retainable, CCK);
4551 }
4552 
4553 /// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
4554 /// type, remove the placeholder cast.
stripARCUnbridgedCast(Expr * e)4555 Expr *SemaObjC::stripARCUnbridgedCast(Expr *e) {
4556   assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4557   ASTContext &Context = getASTContext();
4558 
4559   if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4560     Expr *sub = stripARCUnbridgedCast(pe->getSubExpr());
4561     return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4562   } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4563     assert(uo->getOpcode() == UO_Extension);
4564     Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
4565     return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(),
4566                                  sub->getValueKind(), sub->getObjectKind(),
4567                                  uo->getOperatorLoc(), false,
4568                                  SemaRef.CurFPFeatureOverrides());
4569   } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
4570     assert(!gse->isResultDependent());
4571     assert(!gse->isTypePredicate());
4572 
4573     unsigned n = gse->getNumAssocs();
4574     SmallVector<Expr *, 4> subExprs;
4575     SmallVector<TypeSourceInfo *, 4> subTypes;
4576     subExprs.reserve(n);
4577     subTypes.reserve(n);
4578     for (const GenericSelectionExpr::Association assoc : gse->associations()) {
4579       subTypes.push_back(assoc.getTypeSourceInfo());
4580       Expr *sub = assoc.getAssociationExpr();
4581       if (assoc.isSelected())
4582         sub = stripARCUnbridgedCast(sub);
4583       subExprs.push_back(sub);
4584     }
4585 
4586     return GenericSelectionExpr::Create(
4587         Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4588         subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4589         gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4590   } else {
4591     assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");
4592     return cast<ImplicitCastExpr>(e)->getSubExpr();
4593   }
4594 }
4595 
CheckObjCARCUnavailableWeakConversion(QualType castType,QualType exprType)4596 bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType,
4597                                                      QualType exprType) {
4598   ASTContext &Context = getASTContext();
4599   QualType canCastType =
4600     Context.getCanonicalType(castType).getUnqualifiedType();
4601   QualType canExprType =
4602     Context.getCanonicalType(exprType).getUnqualifiedType();
4603   if (isa<ObjCObjectPointerType>(canCastType) &&
4604       castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
4605       canExprType->isObjCObjectPointerType()) {
4606     if (const ObjCObjectPointerType *ObjT =
4607         canExprType->getAs<ObjCObjectPointerType>())
4608       if (const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl())
4609         return !ObjI->isArcWeakrefUnavailable();
4610   }
4611   return true;
4612 }
4613 
4614 /// Look for an ObjCReclaimReturnedObject cast and destroy it.
maybeUndoReclaimObject(Expr * e)4615 static Expr *maybeUndoReclaimObject(Expr *e) {
4616   Expr *curExpr = e, *prevExpr = nullptr;
4617 
4618   // Walk down the expression until we hit an implicit cast of kind
4619   // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.
4620   while (true) {
4621     if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4622       prevExpr = curExpr;
4623       curExpr = pe->getSubExpr();
4624       continue;
4625     }
4626 
4627     if (auto *ce = dyn_cast<CastExpr>(curExpr)) {
4628       if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4629         if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4630           if (!prevExpr)
4631             return ice->getSubExpr();
4632           if (auto *pe = dyn_cast<ParenExpr>(prevExpr))
4633             pe->setSubExpr(ice->getSubExpr());
4634           else
4635             cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());
4636           return e;
4637         }
4638 
4639       prevExpr = curExpr;
4640       curExpr = ce->getSubExpr();
4641       continue;
4642     }
4643 
4644     // Break out of the loop if curExpr is neither a Paren nor a Cast.
4645     break;
4646   }
4647 
4648   return e;
4649 }
4650 
BuildObjCBridgedCast(SourceLocation LParenLoc,ObjCBridgeCastKind Kind,SourceLocation BridgeKeywordLoc,TypeSourceInfo * TSInfo,Expr * SubExpr)4651 ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc,
4652                                           ObjCBridgeCastKind Kind,
4653                                           SourceLocation BridgeKeywordLoc,
4654                                           TypeSourceInfo *TSInfo,
4655                                           Expr *SubExpr) {
4656   ASTContext &Context = getASTContext();
4657   ExprResult SubResult = SemaRef.UsualUnaryConversions(SubExpr);
4658   if (SubResult.isInvalid()) return ExprError();
4659   SubExpr = SubResult.get();
4660 
4661   QualType T = TSInfo->getType();
4662   QualType FromType = SubExpr->getType();
4663 
4664   CastKind CK;
4665 
4666   bool MustConsume = false;
4667   if (T->isDependentType() || SubExpr->isTypeDependent()) {
4668     // Okay: we'll build a dependent expression type.
4669     CK = CK_Dependent;
4670   } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {
4671     // Casting CF -> id
4672     CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4673                                   : CK_CPointerToObjCPointerCast);
4674     switch (Kind) {
4675     case OBC_Bridge:
4676       break;
4677 
4678     case OBC_BridgeRetained: {
4679       bool br = isKnownName("CFBridgingRelease");
4680       Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4681         << 2
4682         << FromType
4683         << (T->isBlockPointerType()? 1 : 0)
4684         << T
4685         << SubExpr->getSourceRange()
4686         << Kind;
4687       Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4688         << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge");
4689       Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4690         << FromType << br
4691         << FixItHint::CreateReplacement(BridgeKeywordLoc,
4692                                         br ? "CFBridgingRelease "
4693                                            : "__bridge_transfer ");
4694 
4695       Kind = OBC_Bridge;
4696       break;
4697     }
4698 
4699     case OBC_BridgeTransfer:
4700       // We must consume the Objective-C object produced by the cast.
4701       MustConsume = true;
4702       break;
4703     }
4704   } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) {
4705     // Okay: id -> CF
4706     CK = CK_BitCast;
4707     switch (Kind) {
4708     case OBC_Bridge:
4709       // Reclaiming a value that's going to be __bridge-casted to CF
4710       // is very dangerous, so we don't do it.
4711       SubExpr = maybeUndoReclaimObject(SubExpr);
4712       break;
4713 
4714     case OBC_BridgeRetained:
4715       // Produce the object before casting it.
4716       SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,
4717                                          SubExpr, nullptr, VK_PRValue,
4718                                          FPOptionsOverride());
4719       break;
4720 
4721     case OBC_BridgeTransfer: {
4722       bool br = isKnownName("CFBridgingRetain");
4723       Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4724         << (FromType->isBlockPointerType()? 1 : 0)
4725         << FromType
4726         << 2
4727         << T
4728         << SubExpr->getSourceRange()
4729         << Kind;
4730 
4731       Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4732         << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge ");
4733       Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4734         << T << br
4735         << FixItHint::CreateReplacement(BridgeKeywordLoc,
4736                           br ? "CFBridgingRetain " : "__bridge_retained");
4737 
4738       Kind = OBC_Bridge;
4739       break;
4740     }
4741     }
4742   } else {
4743     Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4744       << FromType << T << Kind
4745       << SubExpr->getSourceRange()
4746       << TSInfo->getTypeLoc().getSourceRange();
4747     return ExprError();
4748   }
4749 
4750   Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,
4751                                                    BridgeKeywordLoc,
4752                                                    TSInfo, SubExpr);
4753 
4754   if (MustConsume) {
4755     SemaRef.Cleanup.setExprNeedsCleanups(true);
4756     Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
4757                                       nullptr, VK_PRValue, FPOptionsOverride());
4758   }
4759 
4760   return Result;
4761 }
4762 
ActOnObjCBridgedCast(Scope * S,SourceLocation LParenLoc,ObjCBridgeCastKind Kind,SourceLocation BridgeKeywordLoc,ParsedType Type,SourceLocation RParenLoc,Expr * SubExpr)4763 ExprResult SemaObjC::ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc,
4764                                           ObjCBridgeCastKind Kind,
4765                                           SourceLocation BridgeKeywordLoc,
4766                                           ParsedType Type,
4767                                           SourceLocation RParenLoc,
4768                                           Expr *SubExpr) {
4769   ASTContext &Context = getASTContext();
4770   TypeSourceInfo *TSInfo = nullptr;
4771   QualType T = SemaRef.GetTypeFromParser(Type, &TSInfo);
4772   if (Kind == OBC_Bridge)
4773     CheckTollFreeBridgeCast(T, SubExpr);
4774   if (!TSInfo)
4775     TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4776   return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo,
4777                               SubExpr);
4778 }
4779 
LookupIvarInObjCMethod(LookupResult & Lookup,Scope * S,IdentifierInfo * II)4780 DeclResult SemaObjC::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S,
4781                                             IdentifierInfo *II) {
4782   SourceLocation Loc = Lookup.getNameLoc();
4783   ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl();
4784 
4785   // Check for error condition which is already reported.
4786   if (!CurMethod)
4787     return DeclResult(true);
4788 
4789   // There are two cases to handle here.  1) scoped lookup could have failed,
4790   // in which case we should look for an ivar.  2) scoped lookup could have
4791   // found a decl, but that decl is outside the current instance method (i.e.
4792   // a global variable).  In these two cases, we do a lookup for an ivar with
4793   // this name, if the lookup sucedes, we replace it our current decl.
4794 
4795   // If we're in a class method, we don't normally want to look for
4796   // ivars.  But if we don't find anything else, and there's an
4797   // ivar, that's an error.
4798   bool IsClassMethod = CurMethod->isClassMethod();
4799 
4800   bool LookForIvars;
4801   if (Lookup.empty())
4802     LookForIvars = true;
4803   else if (IsClassMethod)
4804     LookForIvars = false;
4805   else
4806     LookForIvars = (Lookup.isSingleResult() &&
4807                     Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
4808   ObjCInterfaceDecl *IFace = nullptr;
4809   if (LookForIvars) {
4810     IFace = CurMethod->getClassInterface();
4811     ObjCInterfaceDecl *ClassDeclared;
4812     ObjCIvarDecl *IV = nullptr;
4813     if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) {
4814       // Diagnose using an ivar in a class method.
4815       if (IsClassMethod) {
4816         Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4817         return DeclResult(true);
4818       }
4819 
4820       // Diagnose the use of an ivar outside of the declaring class.
4821       if (IV->getAccessControl() == ObjCIvarDecl::Private &&
4822           !declaresSameEntity(ClassDeclared, IFace) &&
4823           !getLangOpts().DebuggerSupport)
4824         Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName();
4825 
4826       // Success.
4827       return IV;
4828     }
4829   } else if (CurMethod->isInstanceMethod()) {
4830     // We should warn if a local variable hides an ivar.
4831     if (ObjCInterfaceDecl *IFace = CurMethod->getClassInterface()) {
4832       ObjCInterfaceDecl *ClassDeclared;
4833       if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
4834         if (IV->getAccessControl() != ObjCIvarDecl::Private ||
4835             declaresSameEntity(IFace, ClassDeclared))
4836           Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4837       }
4838     }
4839   } else if (Lookup.isSingleResult() &&
4840              Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()) {
4841     // If accessing a stand-alone ivar in a class method, this is an error.
4842     if (const ObjCIvarDecl *IV =
4843             dyn_cast<ObjCIvarDecl>(Lookup.getFoundDecl())) {
4844       Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4845       return DeclResult(true);
4846     }
4847   }
4848 
4849   // Didn't encounter an error, didn't find an ivar.
4850   return DeclResult(false);
4851 }
4852 
LookupInObjCMethod(LookupResult & Lookup,Scope * S,IdentifierInfo * II,bool AllowBuiltinCreation)4853 ExprResult SemaObjC::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
4854                                         IdentifierInfo *II,
4855                                         bool AllowBuiltinCreation) {
4856   // FIXME: Integrate this lookup step into LookupParsedName.
4857   DeclResult Ivar = LookupIvarInObjCMethod(Lookup, S, II);
4858   if (Ivar.isInvalid())
4859     return ExprError();
4860   if (Ivar.isUsable())
4861     return BuildIvarRefExpr(S, Lookup.getNameLoc(),
4862                             cast<ObjCIvarDecl>(Ivar.get()));
4863 
4864   if (Lookup.empty() && II && AllowBuiltinCreation)
4865     SemaRef.LookupBuiltin(Lookup);
4866 
4867   // Sentinel value saying that we didn't do anything special.
4868   return ExprResult(false);
4869 }
4870 
BuildIvarRefExpr(Scope * S,SourceLocation Loc,ObjCIvarDecl * IV)4871 ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc,
4872                                       ObjCIvarDecl *IV) {
4873   ASTContext &Context = getASTContext();
4874   ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl();
4875   assert(CurMethod && CurMethod->isInstanceMethod() &&
4876          "should not reference ivar from this context");
4877 
4878   ObjCInterfaceDecl *IFace = CurMethod->getClassInterface();
4879   assert(IFace && "should not reference ivar from this context");
4880 
4881   // If we're referencing an invalid decl, just return this as a silent
4882   // error node.  The error diagnostic was already emitted on the decl.
4883   if (IV->isInvalidDecl())
4884     return ExprError();
4885 
4886   // Check if referencing a field with __attribute__((deprecated)).
4887   if (SemaRef.DiagnoseUseOfDecl(IV, Loc))
4888     return ExprError();
4889 
4890   // FIXME: This should use a new expr for a direct reference, don't
4891   // turn this into Self->ivar, just return a BareIVarExpr or something.
4892   IdentifierInfo &II = Context.Idents.get("self");
4893   UnqualifiedId SelfName;
4894   SelfName.setImplicitSelfParam(&II);
4895   CXXScopeSpec SelfScopeSpec;
4896   SourceLocation TemplateKWLoc;
4897   ExprResult SelfExpr =
4898       SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
4899                                 /*HasTrailingLParen=*/false,
4900                                 /*IsAddressOfOperand=*/false);
4901   if (SelfExpr.isInvalid())
4902     return ExprError();
4903 
4904   SelfExpr = SemaRef.DefaultLvalueConversion(SelfExpr.get());
4905   if (SelfExpr.isInvalid())
4906     return ExprError();
4907 
4908   SemaRef.MarkAnyDeclReferenced(Loc, IV, true);
4909 
4910   ObjCMethodFamily MF = CurMethod->getMethodFamily();
4911   if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&
4912       !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV))
4913     Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();
4914 
4915   ObjCIvarRefExpr *Result = new (Context)
4916       ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc,
4917                       IV->getLocation(), SelfExpr.get(), true, true);
4918 
4919   if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
4920     if (!SemaRef.isUnevaluatedContext() &&
4921         !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
4922       SemaRef.getCurFunction()->recordUseOfWeak(Result);
4923   }
4924   if (getLangOpts().ObjCAutoRefCount && !SemaRef.isUnevaluatedContext())
4925     if (const BlockDecl *BD = SemaRef.CurContext->getInnermostBlockDecl())
4926       SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
4927 
4928   return Result;
4929 }
4930 
FindCompositeObjCPointerType(ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)4931 QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS,
4932                                                 ExprResult &RHS,
4933                                                 SourceLocation QuestionLoc) {
4934   ASTContext &Context = getASTContext();
4935   QualType LHSTy = LHS.get()->getType();
4936   QualType RHSTy = RHS.get()->getType();
4937 
4938   // Handle things like Class and struct objc_class*.  Here we case the result
4939   // to the pseudo-builtin, because that will be implicitly cast back to the
4940   // redefinition type if an attempt is made to access its fields.
4941   if (LHSTy->isObjCClassType() &&
4942       (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
4943     RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,
4944                                     CK_CPointerToObjCPointerCast);
4945     return LHSTy;
4946   }
4947   if (RHSTy->isObjCClassType() &&
4948       (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
4949     LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,
4950                                     CK_CPointerToObjCPointerCast);
4951     return RHSTy;
4952   }
4953   // And the same for struct objc_object* / id
4954   if (LHSTy->isObjCIdType() &&
4955       (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
4956     RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,
4957                                     CK_CPointerToObjCPointerCast);
4958     return LHSTy;
4959   }
4960   if (RHSTy->isObjCIdType() &&
4961       (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
4962     LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,
4963                                     CK_CPointerToObjCPointerCast);
4964     return RHSTy;
4965   }
4966   // And the same for struct objc_selector* / SEL
4967   if (Context.isObjCSelType(LHSTy) &&
4968       (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
4969     RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);
4970     return LHSTy;
4971   }
4972   if (Context.isObjCSelType(RHSTy) &&
4973       (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
4974     LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);
4975     return RHSTy;
4976   }
4977   // Check constraints for Objective-C object pointers types.
4978   if (LHSTy->isObjCObjectPointerType() && RHSTy->isObjCObjectPointerType()) {
4979 
4980     if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
4981       // Two identical object pointer types are always compatible.
4982       return LHSTy;
4983     }
4984     const ObjCObjectPointerType *LHSOPT =
4985         LHSTy->castAs<ObjCObjectPointerType>();
4986     const ObjCObjectPointerType *RHSOPT =
4987         RHSTy->castAs<ObjCObjectPointerType>();
4988     QualType compositeType = LHSTy;
4989 
4990     // If both operands are interfaces and either operand can be
4991     // assigned to the other, use that type as the composite
4992     // type. This allows
4993     //   xxx ? (A*) a : (B*) b
4994     // where B is a subclass of A.
4995     //
4996     // Additionally, as for assignment, if either type is 'id'
4997     // allow silent coercion. Finally, if the types are
4998     // incompatible then make sure to use 'id' as the composite
4999     // type so the result is acceptable for sending messages to.
5000 
5001     // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
5002     // It could return the composite type.
5003     if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
5004              .isNull()) {
5005       // Nothing more to do.
5006     } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5007       compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5008     } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5009       compositeType = LHSOPT->isObjCBuiltinType() ? LHSTy : RHSTy;
5010     } else if ((LHSOPT->isObjCQualifiedIdType() ||
5011                 RHSOPT->isObjCQualifiedIdType()) &&
5012                Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5013                                                          true)) {
5014       // Need to handle "id<xx>" explicitly.
5015       // GCC allows qualified id and any Objective-C type to devolve to
5016       // id. Currently localizing to here until clear this should be
5017       // part of ObjCQualifiedIdTypesAreCompatible.
5018       compositeType = Context.getObjCIdType();
5019     } else if (LHSTy->isObjCIdType() || RHSTy->isObjCIdType()) {
5020       compositeType = Context.getObjCIdType();
5021     } else {
5022       Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5023           << LHSTy << RHSTy << LHS.get()->getSourceRange()
5024           << RHS.get()->getSourceRange();
5025       QualType incompatTy = Context.getObjCIdType();
5026       LHS = SemaRef.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
5027       RHS = SemaRef.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
5028       return incompatTy;
5029     }
5030     // The object pointer types are compatible.
5031     LHS = SemaRef.ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);
5032     RHS = SemaRef.ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);
5033     return compositeType;
5034   }
5035   // Check Objective-C object pointer types and 'void *'
5036   if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) {
5037     if (getLangOpts().ObjCAutoRefCount) {
5038       // ARC forbids the implicit conversion of object pointers to 'void *',
5039       // so these types are not compatible.
5040       Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5041           << LHSTy << RHSTy << LHS.get()->getSourceRange()
5042           << RHS.get()->getSourceRange();
5043       LHS = RHS = true;
5044       return QualType();
5045     }
5046     QualType lhptee = LHSTy->castAs<PointerType>()->getPointeeType();
5047     QualType rhptee = RHSTy->castAs<ObjCObjectPointerType>()->getPointeeType();
5048     QualType destPointee =
5049         Context.getQualifiedType(lhptee, rhptee.getQualifiers());
5050     QualType destType = Context.getPointerType(destPointee);
5051     // Add qualifiers if necessary.
5052     LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
5053     // Promote to void*.
5054     RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
5055     return destType;
5056   }
5057   if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
5058     if (getLangOpts().ObjCAutoRefCount) {
5059       // ARC forbids the implicit conversion of object pointers to 'void *',
5060       // so these types are not compatible.
5061       Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5062           << LHSTy << RHSTy << LHS.get()->getSourceRange()
5063           << RHS.get()->getSourceRange();
5064       LHS = RHS = true;
5065       return QualType();
5066     }
5067     QualType lhptee = LHSTy->castAs<ObjCObjectPointerType>()->getPointeeType();
5068     QualType rhptee = RHSTy->castAs<PointerType>()->getPointeeType();
5069     QualType destPointee =
5070         Context.getQualifiedType(rhptee, lhptee.getQualifiers());
5071     QualType destType = Context.getPointerType(destPointee);
5072     // Add qualifiers if necessary.
5073     RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
5074     // Promote to void*.
5075     LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
5076     return destType;
5077   }
5078   return QualType();
5079 }
5080 
CheckConversionToObjCLiteral(QualType DstType,Expr * & Exp,bool Diagnose)5081 bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp,
5082                                             bool Diagnose) {
5083   if (!getLangOpts().ObjC)
5084     return false;
5085 
5086   const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
5087   if (!PT)
5088     return false;
5089   const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
5090 
5091   // Ignore any parens, implicit casts (should only be
5092   // array-to-pointer decays), and not-so-opaque values.  The last is
5093   // important for making this trigger for property assignments.
5094   Expr *SrcExpr = Exp->IgnoreParenImpCasts();
5095   if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))
5096     if (OV->getSourceExpr())
5097       SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();
5098 
5099   if (auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {
5100     if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString")))
5101       return false;
5102     if (!SL->isOrdinary())
5103       return false;
5104 
5105     if (Diagnose) {
5106       Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5107           << /*string*/ 0 << FixItHint::CreateInsertion(SL->getBeginLoc(), "@");
5108       Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get();
5109     }
5110     return true;
5111   }
5112 
5113   if ((isa<IntegerLiteral>(SrcExpr) || isa<CharacterLiteral>(SrcExpr) ||
5114        isa<FloatingLiteral>(SrcExpr) || isa<ObjCBoolLiteralExpr>(SrcExpr) ||
5115        isa<CXXBoolLiteralExpr>(SrcExpr)) &&
5116       !SrcExpr->isNullPointerConstant(getASTContext(),
5117                                       Expr::NPC_NeverValueDependent)) {
5118     if (!ID || !ID->getIdentifier()->isStr("NSNumber"))
5119       return false;
5120     if (Diagnose) {
5121       Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix)
5122           << /*number*/ 1
5123           << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "@");
5124       Expr *NumLit =
5125           BuildObjCNumericLiteral(SrcExpr->getBeginLoc(), SrcExpr).get();
5126       if (NumLit)
5127         Exp = NumLit;
5128     }
5129     return true;
5130   }
5131 
5132   return false;
5133 }
5134 
5135 /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
ActOnObjCBoolLiteral(SourceLocation OpLoc,tok::TokenKind Kind)5136 ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc,
5137                                           tok::TokenKind Kind) {
5138   assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5139          "Unknown Objective-C Boolean value!");
5140   ASTContext &Context = getASTContext();
5141   QualType BoolT = Context.ObjCBuiltinBoolTy;
5142   if (!Context.getBOOLDecl()) {
5143     LookupResult Result(SemaRef, &Context.Idents.get("BOOL"), OpLoc,
5144                         Sema::LookupOrdinaryName);
5145     if (SemaRef.LookupName(Result, SemaRef.getCurScope()) &&
5146         Result.isSingleResult()) {
5147       NamedDecl *ND = Result.getFoundDecl();
5148       if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND))
5149         Context.setBOOLDecl(TD);
5150     }
5151   }
5152   if (Context.getBOOLDecl())
5153     BoolT = Context.getBOOLType();
5154   return new (Context)
5155       ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc);
5156 }
5157 
ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef<AvailabilitySpec> AvailSpecs,SourceLocation AtLoc,SourceLocation RParen)5158 ExprResult SemaObjC::ActOnObjCAvailabilityCheckExpr(
5159     llvm::ArrayRef<AvailabilitySpec> AvailSpecs, SourceLocation AtLoc,
5160     SourceLocation RParen) {
5161   ASTContext &Context = getASTContext();
5162   auto FindSpecVersion =
5163       [&](StringRef Platform) -> std::optional<VersionTuple> {
5164     auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5165       return Spec.getPlatform() == Platform;
5166     });
5167     // Transcribe the "ios" availability check to "maccatalyst" when compiling
5168     // for "maccatalyst" if "maccatalyst" is not specified.
5169     if (Spec == AvailSpecs.end() && Platform == "maccatalyst") {
5170       Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5171         return Spec.getPlatform() == "ios";
5172       });
5173     }
5174     if (Spec == AvailSpecs.end())
5175       return std::nullopt;
5176     return Spec->getVersion();
5177   };
5178 
5179   VersionTuple Version;
5180   if (auto MaybeVersion =
5181           FindSpecVersion(Context.getTargetInfo().getPlatformName()))
5182     Version = *MaybeVersion;
5183 
5184   // The use of `@available` in the enclosing context should be analyzed to
5185   // warn when it's used inappropriately (i.e. not if(@available)).
5186   if (FunctionScopeInfo *Context = SemaRef.getCurFunctionAvailabilityContext())
5187     Context->HasPotentialAvailabilityViolations = true;
5188 
5189   return new (Context)
5190       ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
5191 }
5192 
5193 /// Prepare a conversion of the given expression to an ObjC object
5194 /// pointer type.
PrepareCastToObjCObjectPointer(ExprResult & E)5195 CastKind SemaObjC::PrepareCastToObjCObjectPointer(ExprResult &E) {
5196   QualType type = E.get()->getType();
5197   if (type->isObjCObjectPointerType()) {
5198     return CK_BitCast;
5199   } else if (type->isBlockPointerType()) {
5200     SemaRef.maybeExtendBlockObject(E);
5201     return CK_BlockPointerToObjCPointerCast;
5202   } else {
5203     assert(type->isPointerType());
5204     return CK_CPointerToObjCPointerCast;
5205   }
5206 }
5207 
CheckLiteralKind(Expr * FromE)5208 SemaObjC::ObjCLiteralKind SemaObjC::CheckLiteralKind(Expr *FromE) {
5209   FromE = FromE->IgnoreParenImpCasts();
5210   switch (FromE->getStmtClass()) {
5211   default:
5212     break;
5213   case Stmt::ObjCStringLiteralClass:
5214     // "string literal"
5215     return LK_String;
5216   case Stmt::ObjCArrayLiteralClass:
5217     // "array literal"
5218     return LK_Array;
5219   case Stmt::ObjCDictionaryLiteralClass:
5220     // "dictionary literal"
5221     return LK_Dictionary;
5222   case Stmt::BlockExprClass:
5223     return LK_Block;
5224   case Stmt::ObjCBoxedExprClass: {
5225     Expr *Inner = cast<ObjCBoxedExpr>(FromE)->getSubExpr()->IgnoreParens();
5226     switch (Inner->getStmtClass()) {
5227     case Stmt::IntegerLiteralClass:
5228     case Stmt::FloatingLiteralClass:
5229     case Stmt::CharacterLiteralClass:
5230     case Stmt::ObjCBoolLiteralExprClass:
5231     case Stmt::CXXBoolLiteralExprClass:
5232       // "numeric literal"
5233       return LK_Numeric;
5234     case Stmt::ImplicitCastExprClass: {
5235       CastKind CK = cast<CastExpr>(Inner)->getCastKind();
5236       // Boolean literals can be represented by implicit casts.
5237       if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)
5238         return LK_Numeric;
5239       break;
5240     }
5241     default:
5242       break;
5243     }
5244     return LK_Boxed;
5245   }
5246   }
5247   return LK_None;
5248 }
5249