summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r--lib/Sema/SemaExprObjC.cpp340
1 files changed, 251 insertions, 89 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index e43b6bf..e7b5ec9 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -12,20 +12,20 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
-#include "clang/Sema/Lookup.h"
-#include "clang/Sema/Scope.h"
-#include "clang/Sema/ScopeInfo.h"
-#include "clang/Sema/Initialization.h"
-#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
-#include "clang/Edit/Rewriters.h"
-#include "clang/Edit/Commit.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeLoc.h"
-#include "llvm/ADT/SmallString.h"
+#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/Rewriters.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "llvm/ADT/SmallString.h"
using namespace clang;
using namespace sema;
@@ -170,9 +170,9 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
QualType NumberType,
bool isLiteral = false,
SourceRange R = SourceRange()) {
- llvm::Optional<NSAPI::NSNumberLiteralMethodKind> Kind
- = S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
-
+ Optional<NSAPI::NSNumberLiteralMethodKind> Kind =
+ S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
+
if (!Kind) {
if (isLiteral) {
S.Diag(Loc, diag::err_invalid_nsnumber_type)
@@ -238,7 +238,7 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
SourceLocation(), SourceLocation(),
&CX.Idents.get("value"),
NumberType, /*TInfo=*/0, SC_None,
- SC_None, 0);
+ 0);
Method->setMethodParams(S.Context, value, ArrayRef<SourceLocation>());
}
@@ -489,7 +489,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
&Context.Idents.get("value"),
Context.getPointerType(ConstCharType),
/*TInfo=*/0,
- SC_None, SC_None, 0);
+ SC_None, 0);
M->setMethodParams(Context, value, ArrayRef<SourceLocation>());
BoxingMethod = M;
}
@@ -656,16 +656,14 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
SourceLocation(),
&Context.Idents.get("objects"),
Context.getPointerType(IdT),
- /*TInfo=*/0, SC_None, SC_None,
- 0);
+ /*TInfo=*/0, SC_None, 0);
Params.push_back(objects);
ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
SourceLocation(),
SourceLocation(),
&Context.Idents.get("cnt"),
Context.UnsignedLongTy,
- /*TInfo=*/0, SC_None, SC_None,
- 0);
+ /*TInfo=*/0, SC_None, 0);
Params.push_back(cnt);
Method->setMethodParams(Context, Params, ArrayRef<SourceLocation>());
}
@@ -774,24 +772,21 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
SourceLocation(),
&Context.Idents.get("objects"),
Context.getPointerType(IdT),
- /*TInfo=*/0, SC_None, SC_None,
- 0);
+ /*TInfo=*/0, SC_None, 0);
Params.push_back(objects);
ParmVarDecl *keys = ParmVarDecl::Create(Context, Method,
SourceLocation(),
SourceLocation(),
&Context.Idents.get("keys"),
Context.getPointerType(IdT),
- /*TInfo=*/0, SC_None, SC_None,
- 0);
+ /*TInfo=*/0, SC_None, 0);
Params.push_back(keys);
ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
SourceLocation(),
SourceLocation(),
&Context.Idents.get("cnt"),
Context.UnsignedLongTy,
- /*TInfo=*/0, SC_None, SC_None,
- 0);
+ /*TInfo=*/0, SC_None, 0);
Params.push_back(cnt);
Method->setMethodParams(Context, Params, ArrayRef<SourceLocation>());
}
@@ -981,7 +976,7 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
llvm::DenseMap<Selector, SourceLocation>::iterator Pos
= ReferencedSelectors.find(Sel);
if (Pos == ReferencedSelectors.end())
- ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
+ ReferencedSelectors.insert(std::make_pair(Sel, AtLoc));
}
// In ARC, forbid the user from using @selector for
@@ -1094,6 +1089,73 @@ QualType Sema::getMessageSendResultType(QualType ReceiverType,
return ReceiverType;
}
+/// Look for an ObjC method whose result type exactly matches the given type.
+static const ObjCMethodDecl *
+findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD,
+ QualType instancetype) {
+ if (MD->getResultType() == instancetype) return MD;
+
+ // For these purposes, a method in an @implementation overrides a
+ // declaration in the @interface.
+ if (const ObjCImplDecl *impl =
+ dyn_cast<ObjCImplDecl>(MD->getDeclContext())) {
+ const ObjCContainerDecl *iface;
+ if (const ObjCCategoryImplDecl *catImpl =
+ dyn_cast<ObjCCategoryImplDecl>(impl)) {
+ iface = catImpl->getCategoryDecl();
+ } else {
+ iface = impl->getClassInterface();
+ }
+
+ const ObjCMethodDecl *ifaceMD =
+ iface->getMethod(MD->getSelector(), MD->isInstanceMethod());
+ if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype);
+ }
+
+ SmallVector<const ObjCMethodDecl *, 4> overrides;
+ MD->getOverriddenMethods(overrides);
+ for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
+ if (const ObjCMethodDecl *result =
+ findExplicitInstancetypeDeclarer(overrides[i], instancetype))
+ return result;
+ }
+
+ return 0;
+}
+
+void Sema::EmitRelatedResultTypeNoteForReturn(QualType destType) {
+ // Only complain if we're in an ObjC method and the required return
+ // type doesn't match the method's declared return type.
+ ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurContext);
+ if (!MD || !MD->hasRelatedResultType() ||
+ Context.hasSameUnqualifiedType(destType, MD->getResultType()))
+ return;
+
+ // Look for a method overridden by this method which explicitly uses
+ // 'instancetype'.
+ if (const ObjCMethodDecl *overridden =
+ findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) {
+ SourceLocation loc;
+ SourceRange range;
+ if (TypeSourceInfo *TSI = overridden->getResultTypeSourceInfo()) {
+ range = TSI->getTypeLoc().getSourceRange();
+ loc = range.getBegin();
+ }
+ if (loc.isInvalid())
+ loc = overridden->getLocation();
+ Diag(loc, diag::note_related_result_type_explicit)
+ << /*current method*/ 1 << range;
+ return;
+ }
+
+ // Otherwise, if we have an interesting method family, note that.
+ // This should always trigger if the above didn't.
+ if (ObjCMethodFamily family = MD->getMethodFamily())
+ Diag(MD->getLocation(), diag::note_related_result_type_family)
+ << /*current method*/ 1
+ << family;
+}
+
void Sema::EmitRelatedResultTypeNote(const Expr *E) {
E = E->IgnoreParenImpCasts();
const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
@@ -1135,10 +1197,16 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
if (Args[i]->isTypeDependent())
continue;
- ExprResult Result = DefaultArgumentPromotion(Args[i]);
- if (Result.isInvalid())
+ ExprResult result;
+ if (getLangOpts().DebuggerSupport) {
+ QualType paramTy; // ignored
+ result = checkUnknownAnyArg(lbrac, Args[i], paramTy);
+ } else {
+ result = DefaultArgumentPromotion(Args[i]);
+ }
+ if (result.isInvalid())
return true;
- Args[i] = Result.take();
+ Args[i] = result.take();
}
unsigned DiagID;
@@ -1196,6 +1264,22 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
!param->hasAttr<CFConsumedAttr>())
argExpr = stripARCUnbridgedCast(argExpr);
+ // If the parameter is __unknown_anytype, infer its type
+ // from the argument.
+ if (param->getType() == Context.UnknownAnyTy) {
+ QualType paramType;
+ ExprResult argE = checkUnknownAnyArg(lbrac, argExpr, paramType);
+ if (argE.isInvalid()) {
+ IsError = true;
+ } else {
+ Args[i] = argE.take();
+
+ // Update the parameter type in-place.
+ param->setType(paramType);
+ }
+ continue;
+ }
+
if (RequireCompleteType(argExpr->getSourceRange().getBegin(),
param->getType(),
diag::err_call_incomplete_argument, argExpr))
@@ -1539,8 +1623,15 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) {
if (CurMethod->isInstanceMethod()) {
- QualType T =
- Context.getObjCInterfaceType(CurMethod->getClassInterface());
+ ObjCInterfaceDecl *Super =
+ CurMethod->getClassInterface()->getSuperClass();
+ if (!Super) {
+ // The current class does not have a superclass.
+ Diag(receiverNameLoc, diag::error_root_class_cannot_use_super)
+ << CurMethod->getClassInterface()->getIdentifier();
+ return ExprError();
+ }
+ QualType T = Context.getObjCInterfaceType(Super);
T = Context.getObjCObjectPointerType(T);
return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(),
@@ -1695,9 +1786,11 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
QualType T;
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
T = Context.getObjCInterfaceType(Class);
- else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
+ else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {
T = Context.getTypeDeclType(Type);
- else
+ DiagnoseUseOfDecl(Type, NameLoc);
+ }
+ else
return ObjCInstanceMessage;
// We have a class message, and T is the type we're
@@ -2106,8 +2199,46 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
return ExprError();
Receiver = Result.take();
ReceiverType = Receiver->getType();
+
+ // If the receiver is an ObjC pointer, a block pointer, or an
+ // __attribute__((NSObject)) pointer, we don't need to do any
+ // special conversion in order to look up a receiver.
+ if (ReceiverType->isObjCRetainableType()) {
+ // do nothing
+ } else if (!getLangOpts().ObjCAutoRefCount &&
+ !Context.getObjCIdType().isNull() &&
+ (ReceiverType->isPointerType() ||
+ ReceiverType->isIntegerType())) {
+ // Implicitly convert integers and pointers to 'id' but emit a warning.
+ // But not in ARC.
+ Diag(Loc, diag::warn_bad_receiver_type)
+ << ReceiverType
+ << Receiver->getSourceRange();
+ if (ReceiverType->isPointerType()) {
+ Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
+ CK_CPointerToObjCPointerCast).take();
+ } else {
+ // TODO: specialized warning on null receivers?
+ bool IsNull = Receiver->isNullPointerConstant(Context,
+ Expr::NPC_ValueDependentIsNull);
+ CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
+ Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
+ Kind).take();
+ }
+ ReceiverType = Receiver->getType();
+ } else if (getLangOpts().CPlusPlus) {
+ ExprResult result = PerformContextuallyConvertToObjCPointer(Receiver);
+ if (result.isUsable()) {
+ Receiver = result.take();
+ ReceiverType = Receiver->getType();
+ }
+ }
}
+ // There's a somewhat weird interaction here where we assume that we
+ // won't actually have a method unless we also don't need to do some
+ // of the more detailed type-checking on the receiver.
+
if (!Method) {
// Handle messages to id.
bool receiverIsId = ReceiverType->isObjCIdType();
@@ -2223,7 +2354,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!Method && getLangOpts().ObjCAutoRefCount) {
Diag(Loc, diag::err_arc_may_not_respond)
- << OCIType->getPointeeType() << Sel;
+ << OCIType->getPointeeType() << Sel
+ << SourceRange(SelectorLocs.front(), SelectorLocs.back());
return ExprError();
}
@@ -2242,48 +2374,11 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
}
if (Method && DiagnoseUseOfDecl(Method, Loc, forwardClass))
return ExprError();
- } else if (!getLangOpts().ObjCAutoRefCount &&
- !Context.getObjCIdType().isNull() &&
- (ReceiverType->isPointerType() ||
- ReceiverType->isIntegerType())) {
- // Implicitly convert integers and pointers to 'id' but emit a warning.
- // But not in ARC.
- Diag(Loc, diag::warn_bad_receiver_type)
- << ReceiverType
- << Receiver->getSourceRange();
- if (ReceiverType->isPointerType())
- Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
- CK_CPointerToObjCPointerCast).take();
- else {
- // TODO: specialized warning on null receivers?
- bool IsNull = Receiver->isNullPointerConstant(Context,
- Expr::NPC_ValueDependentIsNull);
- CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
- Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
- Kind).take();
- }
- ReceiverType = Receiver->getType();
} else {
- ExprResult ReceiverRes;
- if (getLangOpts().CPlusPlus)
- ReceiverRes = PerformContextuallyConvertToObjCPointer(Receiver);
- if (ReceiverRes.isUsable()) {
- Receiver = ReceiverRes.take();
- return BuildInstanceMessage(Receiver,
- ReceiverType,
- SuperLoc,
- Sel,
- Method,
- LBracLoc,
- SelectorLocs,
- RBracLoc,
- ArgsIn);
- } else {
- // Reject other random receiver types (e.g. structs).
- Diag(Loc, diag::err_bad_receiver_type)
- << ReceiverType << Receiver->getSourceRange();
- return ExprError();
- }
+ // Reject other random receiver types (e.g. structs).
+ Diag(Loc, diag::err_bad_receiver_type)
+ << ReceiverType << Receiver->getSourceRange();
+ return ExprError();
}
}
}
@@ -2447,6 +2542,18 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
return MaybeBindToTemporary(Result);
}
+static void RemoveSelectorFromWarningCache(Sema &S, Expr* Arg) {
+ if (ObjCSelectorExpr *OSE =
+ dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) {
+ Selector Sel = OSE->getSelector();
+ SourceLocation Loc = OSE->getAtLoc();
+ llvm::DenseMap<Selector, SourceLocation>::iterator Pos
+ = S.ReferencedSelectors.find(Sel);
+ if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)
+ S.ReferencedSelectors.erase(Pos);
+ }
+}
+
// ActOnInstanceMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
@@ -2460,6 +2567,20 @@ ExprResult Sema::ActOnInstanceMessage(Scope *S,
if (!Receiver)
return ExprError();
+ // A ParenListExpr can show up while doing error recovery with invalid code.
+ if (isa<ParenListExpr>(Receiver)) {
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver);
+ if (Result.isInvalid()) return ExprError();
+ Receiver = Result.take();
+ }
+
+ if (RespondsToSelectorSel.isNull()) {
+ IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");
+ RespondsToSelectorSel = Context.Selectors.getUnarySelector(SelectorId);
+ }
+ if (Sel == RespondsToSelectorSel)
+ RemoveSelectorFromWarningCache(*this, Args[0]);
+
return BuildInstanceMessage(Receiver, Receiver->getType(),
/*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0,
LBracLoc, SelectorLocs, RBracLoc, Args);
@@ -2770,19 +2891,36 @@ static void addFixitForObjCARCConversion(Sema &S,
SourceLocation afterLParen,
QualType castType,
Expr *castExpr,
+ Expr *realCast,
const char *bridgeKeyword,
const char *CFBridgeName) {
// We handle C-style and implicit casts here.
switch (CCK) {
case Sema::CCK_ImplicitConversion:
case Sema::CCK_CStyleCast:
+ case Sema::CCK_OtherCast:
break;
case Sema::CCK_FunctionalCast:
- case Sema::CCK_OtherCast:
return;
}
if (CFBridgeName) {
+ if (CCK == Sema::CCK_OtherCast) {
+ if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
+ SourceRange range(NCE->getOperatorLoc(),
+ NCE->getAngleBrackets().getEnd());
+ SmallString<32> BridgeCall;
+
+ SourceManager &SM = S.getSourceManager();
+ char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
+ if (Lexer::isIdentifierBodyChar(PrevChar, S.getLangOpts()))
+ BridgeCall += ' ';
+
+ BridgeCall += CFBridgeName;
+ DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall));
+ }
+ return;
+ }
Expr *castedE = castExpr;
if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))
castedE = CCE->getSubExpr();
@@ -2814,6 +2952,16 @@ static void addFixitForObjCARCConversion(Sema &S,
if (CCK == Sema::CCK_CStyleCast) {
DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
+ } else if (CCK == Sema::CCK_OtherCast) {
+ if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
+ std::string castCode = "(";
+ castCode += bridgeKeyword;
+ castCode += castType.getAsString();
+ castCode += ")";
+ SourceRange Range(NCE->getOperatorLoc(),
+ NCE->getAngleBrackets().getEnd());
+ DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode));
+ }
} else {
std::string castCode = "(";
castCode += bridgeKeyword;
@@ -2838,7 +2986,8 @@ static void addFixitForObjCARCConversion(Sema &S,
static void
diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
QualType castType, ARCConversionTypeClass castACTC,
- Expr *castExpr, ARCConversionTypeClass exprACTC,
+ Expr *castExpr, Expr *realCast,
+ ARCConversionTypeClass exprACTC,
Sema::CheckedConversionKind CCK) {
SourceLocation loc =
(castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());
@@ -2885,17 +3034,24 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
if (CreateRule != ACC_plusOne)
{
- DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
+ DiagnosticBuilder DiagB =
+ (CCK != Sema::CCK_OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge)
+ : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
+
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
- castType, castExpr, "__bridge ", 0);
+ castType, castExpr, realCast, "__bridge ", 0);
}
if (CreateRule != ACC_plusZero)
{
- DiagnosticBuilder DiagB = S.Diag(br ? castExpr->getExprLoc() : noteLoc,
- diag::note_arc_bridge_transfer)
- << castExprType << br;
+ DiagnosticBuilder DiagB =
+ (CCK == Sema::CCK_OtherCast && !br) ?
+ S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer) << castExprType :
+ S.Diag(br ? castExpr->getExprLoc() : noteLoc,
+ diag::note_arc_bridge_transfer)
+ << castExprType << br;
+
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
- castType, castExpr, "__bridge_transfer ",
+ castType, castExpr, realCast, "__bridge_transfer ",
br ? "CFBridgingRelease" : 0);
}
@@ -2918,17 +3074,23 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
if (CreateRule != ACC_plusOne)
{
- DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
+ DiagnosticBuilder DiagB =
+ (CCK != Sema::CCK_OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge)
+ : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
- castType, castExpr, "__bridge ", 0);
+ castType, castExpr, realCast, "__bridge ", 0);
}
if (CreateRule != ACC_plusZero)
{
- DiagnosticBuilder DiagB = S.Diag(br ? castExpr->getExprLoc() : noteLoc,
- diag::note_arc_bridge_retained)
- << castType << br;
+ DiagnosticBuilder DiagB =
+ (CCK == Sema::CCK_OtherCast && !br) ?
+ S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained) << castType :
+ S.Diag(br ? castExpr->getExprLoc() : noteLoc,
+ diag::note_arc_bridge_retained)
+ << castType << br;
+
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
- castType, castExpr, "__bridge_retained ",
+ castType, castExpr, realCast, "__bridge_retained ",
br ? "CFBridgingRetain" : 0);
}
@@ -3025,7 +3187,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
return ACR_unbridged;
diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
- castExpr, exprACTC, CCK);
+ castExpr, castExpr, exprACTC, CCK);
return ACR_okay;
}
@@ -3060,7 +3222,7 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) {
assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable);
diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
- castExpr, ACTC_retainable, CCK);
+ castExpr, realCast, ACTC_retainable, CCK);
}
/// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
OpenPOWER on IntegriCloud