diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 26 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 9 |
3 files changed, 37 insertions, 3 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 875da1a1d9..771af4bf0c 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3469,6 +3469,11 @@ public: bool AllowExplicit = false, bool Elidable = false); bool PerformImplicitConversion(Expr *&From, QualType ToType, + const char *Flavor, + bool AllowExplicit, + bool Elidable, + ImplicitConversionSequence& ICS); + bool PerformImplicitConversion(Expr *&From, QualType ToType, const ImplicitConversionSequence& ICS, const char *Flavor); bool PerformImplicitConversion(Expr *&From, QualType ToType, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 1896fb0dc3..a4679e0e28 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3478,7 +3478,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, OverloadCandidateSet CandidateSet; OverloadedFunctionDecl *Conversions - = T2RecordDecl->getConversionFunctions(); + = T2RecordDecl->getVisibleConversionFunctions(); for (OverloadedFunctionDecl::function_iterator Func = Conversions->function_begin(); Func != Conversions->function_end(); ++Func) { @@ -3489,7 +3489,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl()); else Conv = cast<CXXConversionDecl>(*Func); - + // If the conversion function doesn't return a reference type, // it can't be considered for this conversion. if (Conv->getConversionType()->isLValueReferenceType() && @@ -3688,7 +3688,27 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, } return ICS->ConversionKind == ImplicitConversionSequence::BadConversion; } else { - return PerformImplicitConversion(Init, T1, "initializing"); + ImplicitConversionSequence Conversions; + bool badConversion = PerformImplicitConversion(Init, T1, "initializing", + false, false, + Conversions); + if (badConversion) { + if ((Conversions.ConversionKind == + ImplicitConversionSequence::BadConversion) + && Conversions.ConversionFunctionSet.size() > 0) { + Diag(Init->getSourceRange().getBegin(), + diag::err_lvalue_to_rvalue_ambig_ref) << Init->getSourceRange(); + for (int j = Conversions.ConversionFunctionSet.size()-1; + j >= 0; j--) { + FunctionDecl *Func = Conversions.ConversionFunctionSet[j]; + Diag(Func->getLocation(), diag::err_ovl_candidate); + } + } + else + Diag(Init->getSourceRange().getBegin(), diag::err_lvalue_to_rvalue_ref) + << Init->getSourceRange(); + } + return badConversion; } } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 79909b557d..f500e132de 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -996,6 +996,15 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, const char *Flavor, bool AllowExplicit, bool Elidable) { ImplicitConversionSequence ICS; + return PerformImplicitConversion(From, ToType, Flavor, AllowExplicit, + Elidable, ICS); +} + +bool +Sema::PerformImplicitConversion(Expr *&From, QualType ToType, + const char *Flavor, bool AllowExplicit, + bool Elidable, + ImplicitConversionSequence& ICS) { ICS.ConversionKind = ImplicitConversionSequence::BadConversion; if (Elidable && getLangOptions().CPlusPlus0x) { ICS = TryImplicitConversion(From, ToType, |