зеркало из https://github.com/microsoft/clang-1.git
Patch to implement static casting which requires one
user-defined type conversion. Fixes PR5040. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83211 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
85caf03ee4
Коммит
249ceade49
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s &&
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
|
||||
// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
|
||||
// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
|
||||
// RUN: true
|
||||
|
||||
struct A {
|
||||
A(int);
|
||||
};
|
||||
|
||||
struct B {
|
||||
B(A);
|
||||
};
|
||||
|
||||
int main () {
|
||||
(B)10;
|
||||
B(10);
|
||||
static_cast<B>(10);
|
||||
}
|
||||
|
||||
// CHECK-LP64: call __ZN1AC1Ei
|
||||
// CHECK-LP64: call __ZN1BC1E1A
|
||||
// CHECK-LP64: call __ZN1AC1Ei
|
||||
// CHECK-LP64: call __ZN1BC1E1A
|
||||
// CHECK-LP64: call __ZN1AC1Ei
|
||||
// CHECK-LP64: call __ZN1BC1E1A
|
||||
|
||||
// CHECK-LP32: call L__ZN1AC1Ei
|
||||
// CHECK-LP32: call L__ZN1BC1E1A
|
||||
// CHECK-LP32: call L__ZN1AC1Ei
|
||||
// CHECK-LP32: call L__ZN1BC1E1A
|
||||
// CHECK-LP32: call L__ZN1AC1Ei
|
||||
// CHECK-LP32: call L__ZN1BC1E1A
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
|
||||
|
||||
struct R {
|
||||
R(int);
|
||||
};
|
||||
|
||||
struct A {
|
||||
A(R);
|
||||
};
|
||||
|
||||
struct B {
|
||||
B(A);
|
||||
};
|
||||
|
||||
int main () {
|
||||
B(10); // expected-error {{functional-style cast from 'int' to 'struct B' is not allowed}}
|
||||
(B)10; // expected-error {{C-style cast from 'int' to 'struct B' is not allowed}}
|
||||
static_cast<B>(10); // expected-error {{static_cast from 'int' to 'struct B' is not allowed}} \\
|
||||
// expected-warning {{expression result unused}}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче