From 1f1b08463ee3a13e3ce85678216e4546eb85c0ff Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 18 Dec 2013 21:46:16 +0000 Subject: [PATCH] Allow Objective-C pointer conversions following an explicit user conversion. Finishes the work started in r194224, and fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197609 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 4 ++-- lib/Sema/SemaInit.cpp | 12 ++++++++---- test/SemaObjCXX/contextual-convert-to-id.mm | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 0e4ab07af0..75e1a341ed 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2162,13 +2162,13 @@ public: CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet& CandidateSet, - bool AllowObjCConversionOnExplicit = false); + bool AllowObjCConversionOnExplicit); void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, - bool AllowObjCConversionOnExplicit = false); + bool AllowObjCConversionOnExplicit); void AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 9ba873a078..ae0f662562 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3522,10 +3522,13 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, if (ConvTemplate) S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC, Initializer, - DestType, CandidateSet); + DestType, CandidateSet, + /*AllowObjCConversionOnExplicit=*/ + false); else S.AddConversionCandidate(Conv, I.getPair(), ActingDC, - Initializer, DestType, CandidateSet); + Initializer, DestType, CandidateSet, + /*AllowObjCConversionOnExplicit=*/false); } } } @@ -4145,10 +4148,11 @@ static void TryUserDefinedConversion(Sema &S, if (ConvTemplate) S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC, Initializer, DestType, - CandidateSet); + CandidateSet, AllowExplicit); else S.AddConversionCandidate(Conv, I.getPair(), ActingDC, - Initializer, DestType, CandidateSet); + Initializer, DestType, CandidateSet, + AllowExplicit); } } } diff --git a/test/SemaObjCXX/contextual-convert-to-id.mm b/test/SemaObjCXX/contextual-convert-to-id.mm index 602d6c24a8..47a9d07d41 100644 --- a/test/SemaObjCXX/contextual-convert-to-id.mm +++ b/test/SemaObjCXX/contextual-convert-to-id.mm @@ -8,6 +8,10 @@ - unknownMethod; @end +@interface C : A +- knownMethod; +@end + template struct RetainPtr { explicit operator T*() const; }; @@ -17,6 +21,16 @@ void methodCallToSpecific(RetainPtr a) { [a unknownMethod]; // expected-warning{{'A' may not respond to 'unknownMethod'}} } +void explicitCast(RetainPtr a, RetainPtr b, RetainPtr c) { + (void)(A*)a; + (void)(A*)b; // expected-error{{cannot convert 'RetainPtr' to 'A *' without a conversion operator}} + (void)(A*)c; + (void)(C*)a; + (void)static_cast(a); + (void)static_cast(b); // expected-error{{cannot convert 'RetainPtr' to 'A *' without a conversion operator}} + (void)static_cast(c); +} + struct Incomplete; // expected-note{{forward declaration}} void methodCallToIncomplete(Incomplete &incomplete) { @@ -31,3 +45,8 @@ void methodCallToId(IdPtr a) { [a knownMethod]; [a unknownMethod]; } + +void explicitCast(IdPtr a) { + (void)(A*)a; + (void)static_cast(a); +} -- 2.40.0