diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 13 |
2 files changed, 29 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index bf4abfcb746..58c212b62f9 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11850,6 +11850,22 @@ ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) { return RebuildUnknownAnyExpr(*this, ToType).Visit(E); } +QualType Sema::checkUnknownAnyArg(Expr *&arg) { + // Filter out placeholders. + ExprResult argR = CheckPlaceholderExpr(arg); + if (argR.isInvalid()) return QualType(); + arg = argR.take(); + + // If the argument is an explicit cast, use that exact type as the + // effective parameter type. + if (ExplicitCastExpr *castArg = dyn_cast<ExplicitCastExpr>(arg)) { + return castArg->getTypeAsWritten(); + } + + // Otherwise, try to pass by value. + return arg->getType().getUnqualifiedType(); +} + static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { Expr *orig = E; unsigned diagID = diag::err_uncasted_use_of_unknown_any; diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index e43b6bff558..b0f9958bb52 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1196,6 +1196,19 @@ 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 = checkUnknownAnyArg(argExpr); + if (paramType.isNull()) { + IsError = true; + continue; + } + + // Update the parameter type in-place. + param->setType(paramType); + } + if (RequireCompleteType(argExpr->getSourceRange().getBegin(), param->getType(), diag::err_call_incomplete_argument, argExpr)) |

