summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r--lib/Sema/SemaExprObjC.cpp49
1 files changed, 41 insertions, 8 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 28581bad1a7a4..6ed5047c35daa 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -564,6 +564,13 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
BoxingMethod = StringWithUTF8StringMethod;
BoxedType = NSStringPointer;
+ // Transfer the nullability from method's return type.
+ Optional<NullabilityKind> Nullability =
+ BoxingMethod->getReturnType()->getNullability(Context);
+ if (Nullability)
+ BoxedType = Context.getAttributedType(
+ AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
+ BoxedType);
}
} else if (ValueType->isBuiltinType()) {
// The other types we support are numeric, char and BOOL/bool. We could also
@@ -2705,6 +2712,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
}
}
+ if (ReceiverType->isObjCIdType() && !isImplicit)
+ Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);
+
// 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.
@@ -4314,14 +4324,37 @@ bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType,
/// Look for an ObjCReclaimReturnedObject cast and destroy it.
static Expr *maybeUndoReclaimObject(Expr *e) {
- // For now, we just undo operands that are *immediately* reclaim
- // expressions, which prevents the vast majority of potential
- // problems here. To catch them all, we'd need to rebuild arbitrary
- // value-propagating subexpressions --- we can't reliably rebuild
- // in-place because of expression sharing.
- if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- if (ice->getCastKind() == CK_ARCReclaimReturnedObject)
- return ice->getSubExpr();
+ Expr *curExpr = e, *prevExpr = nullptr;
+
+ // Walk down the expression until we hit an implicit cast of kind
+ // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.
+ while (true) {
+ if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {
+ prevExpr = curExpr;
+ curExpr = pe->getSubExpr();
+ continue;
+ }
+
+ if (auto *ce = dyn_cast<CastExpr>(curExpr)) {
+ if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))
+ if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
+ if (!prevExpr)
+ return ice->getSubExpr();
+ if (auto *pe = dyn_cast<ParenExpr>(prevExpr))
+ pe->setSubExpr(ice->getSubExpr());
+ else
+ cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());
+ return e;
+ }
+
+ prevExpr = curExpr;
+ curExpr = ce->getSubExpr();
+ continue;
+ }
+
+ // Break out of the loop if curExpr is neither a Paren nor a Cast.
+ break;
+ }
return e;
}