diff options
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 12 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/contextual-convert-to-id.mm | 19 |
3 files changed, 29 insertions, 6 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 0e4ab07af01..75e1a341ed4 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 9ba873a0780..ae0f662562e 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/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/clang/test/SemaObjCXX/contextual-convert-to-id.mm b/clang/test/SemaObjCXX/contextual-convert-to-id.mm index 602d6c24a8d..47a9d07d41c 100644 --- a/clang/test/SemaObjCXX/contextual-convert-to-id.mm +++ b/clang/test/SemaObjCXX/contextual-convert-to-id.mm @@ -8,6 +8,10 @@ - unknownMethod; @end +@interface C : A +- knownMethod; +@end + template<typename T> struct RetainPtr { explicit operator T*() const; }; @@ -17,6 +21,16 @@ void methodCallToSpecific(RetainPtr<A> a) { [a unknownMethod]; // expected-warning{{'A' may not respond to 'unknownMethod'}} } +void explicitCast(RetainPtr<A> a, RetainPtr<B> b, RetainPtr<C> c) { + (void)(A*)a; + (void)(A*)b; // expected-error{{cannot convert 'RetainPtr<B>' to 'A *' without a conversion operator}} + (void)(A*)c; + (void)(C*)a; + (void)static_cast<A*>(a); + (void)static_cast<A*>(b); // expected-error{{cannot convert 'RetainPtr<B>' to 'A *' without a conversion operator}} + (void)static_cast<A*>(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*>(a); +} |