summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/Sema.h6
-rw-r--r--clang/lib/Sema/SemaCXXCast.cpp3
-rw-r--r--clang/lib/Sema/SemaOverload.cpp19
3 files changed, 20 insertions, 8 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 60220834dba..b234d56fa01 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -766,7 +766,8 @@ public:
bool SuppressUserConversions,
bool AllowExplicit,
bool ForceRValue,
- bool InOverloadResolution);
+ bool InOverloadResolution,
+ bool UserCast = false);
bool IsStandardConversion(Expr *From, QualType ToType,
bool InOverloadResolution,
StandardConversionSequence& SCS);
@@ -790,7 +791,8 @@ public:
UserDefinedConversionSequence& User,
OverloadCandidateSet& Conversions,
bool AllowConversionFunctions,
- bool AllowExplicit, bool ForceRValue);
+ bool AllowExplicit, bool ForceRValue,
+ bool UserCast = false);
bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp
index e5c4390752c..9822a44b0f8 100644
--- a/clang/lib/Sema/SemaCXXCast.cpp
+++ b/clang/lib/Sema/SemaCXXCast.cpp
@@ -806,7 +806,8 @@ TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType,
/*SuppressUserConversions=*/false,
/*AllowExplicit=*/true,
/*ForceRValue=*/false,
- /*InOverloadResolution=*/false);
+ /*InOverloadResolution=*/false,
+ /*one of user provided casts*/true);
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion)
return TC_NotApplicable;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6966926e9e9..18614f78709 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -404,11 +404,14 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
/// permitted.
/// If @p ForceRValue, then overloading is performed as if From was an rvalue,
/// no matter its actual lvalueness.
+/// If @p UserCast, the implicit conversion is being done for a user-specified
+/// cast.
ImplicitConversionSequence
Sema::TryImplicitConversion(Expr* From, QualType ToType,
bool SuppressUserConversions,
bool AllowExplicit, bool ForceRValue,
- bool InOverloadResolution) {
+ bool InOverloadResolution,
+ bool UserCast) {
ImplicitConversionSequence ICS;
OverloadCandidateSet Conversions;
OverloadingResult UserDefResult = OR_Success;
@@ -419,7 +422,7 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
ICS.UserDefined,
Conversions,
!SuppressUserConversions, AllowExplicit,
- ForceRValue)) == OR_Success) {
+ ForceRValue, UserCast)) == OR_Success) {
ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
// C++ [over.ics.user]p4:
// A conversion of an expression of class type to the same class
@@ -1372,12 +1375,15 @@ static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function,
///
/// \param ForceRValue true if the expression should be treated as an rvalue
/// for overload resolution.
+/// \param UserCast true if looking for user defined conversion for a static
+/// cast.
Sema::OverloadingResult Sema::IsUserDefinedConversion(
Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
OverloadCandidateSet& CandidateSet,
bool AllowConversionFunctions,
- bool AllowExplicit, bool ForceRValue) {
+ bool AllowExplicit, bool ForceRValue,
+ bool UserCast) {
if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
if (CXXRecordDecl *ToRecordDecl
= dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
@@ -1411,11 +1417,14 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
if (ConstructorTmpl)
AddTemplateOverloadCandidate(ConstructorTmpl, false, 0, 0, &From,
1, CandidateSet,
- /*SuppressUserConversions=*/true,
+ /*SuppressUserConversions=*/!UserCast,
ForceRValue);
else
+ // Allow one user-defined conversion when user specifies a
+ // From->ToType conversion via an static cast (c-style, etc).
AddOverloadCandidate(Constructor, &From, 1, CandidateSet,
- /*SuppressUserConversions=*/true, ForceRValue);
+ /*SuppressUserConversions=*/!UserCast,
+ ForceRValue);
}
}
}
OpenPOWER on IntegriCloud