forked from OSchip/llvm-project
When sending a message to a receiver that has "unknown any" type,
force the unknown any type to "id" so that the message send can be completed without requiring a case. Fixes <rdar://problem/10506646>. llvm-svn: 145552
This commit is contained in:
parent
79d0428046
commit
d8fb1e30eb
|
@ -5873,6 +5873,10 @@ public:
|
|||
Expr *CastExpr, CastKind &CastKind,
|
||||
ExprValueKind &VK, CXXCastPath &Path);
|
||||
|
||||
/// \brief Force an expression with unknown-type to an expression of the
|
||||
/// given type.
|
||||
ExprResult forceUnknownAnyToType(Expr *E, QualType ToType);
|
||||
|
||||
// CheckVectorCast - check type constraints for vectors.
|
||||
// Since vectors are an extension, there are no C standard reference for this.
|
||||
// We allow casting between vectors and integer datatypes of the same size.
|
||||
|
|
|
@ -3691,6 +3691,11 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
|
|||
}
|
||||
|
||||
// If we're directly calling a function, get the appropriate declaration.
|
||||
if (Fn->getType() == Context.UnknownAnyTy) {
|
||||
ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
|
||||
if (result.isInvalid()) return ExprError();
|
||||
Fn = result.take();
|
||||
}
|
||||
|
||||
Expr *NakedFn = Fn->IgnoreParens();
|
||||
|
||||
|
@ -10110,6 +10115,10 @@ ExprResult Sema::checkUnknownAnyCast(SourceRange TypeRange, QualType CastType,
|
|||
return CastExpr;
|
||||
}
|
||||
|
||||
ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) {
|
||||
return RebuildUnknownAnyExpr(*this, ToType).Visit(E);
|
||||
}
|
||||
|
||||
static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
|
||||
Expr *orig = E;
|
||||
unsigned diagID = diag::err_uncasted_use_of_unknown_any;
|
||||
|
|
|
@ -1211,9 +1211,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
// and determine receiver type.
|
||||
if (Receiver) {
|
||||
if (Receiver->hasPlaceholderType()) {
|
||||
ExprResult result = CheckPlaceholderExpr(Receiver);
|
||||
if (result.isInvalid()) return ExprError();
|
||||
Receiver = result.take();
|
||||
ExprResult Result;
|
||||
if (Receiver->getType() == Context.UnknownAnyTy)
|
||||
Result = forceUnknownAnyToType(Receiver, Context.getObjCIdType());
|
||||
else
|
||||
Result = CheckPlaceholderExpr(Receiver);
|
||||
if (Result.isInvalid()) return ExprError();
|
||||
Receiver = Result.take();
|
||||
}
|
||||
|
||||
if (Receiver->isTypeDependent()) {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// RUN: %clang_cc1 -funknown-anytype -fsyntax-only -fdebugger-support -verify %s
|
||||
|
||||
extern __unknown_anytype test0;
|
||||
extern __unknown_anytype test1();
|
||||
|
||||
@interface A
|
||||
- (int*)getIntPtr;
|
||||
- (double*)getSomePtr;
|
||||
@end
|
||||
|
||||
@interface B
|
||||
- (float*)getFloatPtr;
|
||||
- (short*)getSomePtr;
|
||||
@end
|
||||
|
||||
void test_unknown_anytype_receiver() {
|
||||
int *ip = [test0 getIntPtr];
|
||||
float *fp = [test1() getFloatPtr];
|
||||
double *dp = [test1() getSomePtr]; // okay: picks first method found
|
||||
[[test0 unknownMethod] otherUnknownMethod]; // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}}
|
||||
(void)(int)[[test0 unknownMethod] otherUnknownMethod];;
|
||||
[[test1() unknownMethod] otherUnknownMethod]; // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}}
|
||||
(void)(id)[[test1() unknownMethod] otherUnknownMethod];
|
||||
}
|
Loading…
Reference in New Issue