diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp | 49 | 
1 files changed, 41 insertions, 8 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp index 28581bad1a7a..6ed5047c35da 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp +++ b/contrib/llvm/tools/clang/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;  }  | 
