summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp16
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp13
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))
OpenPOWER on IntegriCloud