forked from OSchip/llvm-project
Used visible conversion function api to do overload
resolution of type conversion functions in base and current class. llvm-svn: 81784
This commit is contained in:
parent
37a118520c
commit
f4061e39a3
|
@ -1412,9 +1412,8 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
|
|||
if (CXXRecordDecl *FromRecordDecl
|
||||
= dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
|
||||
// Add all of the conversion functions as candidates.
|
||||
// FIXME: Look for conversions in base classes!
|
||||
OverloadedFunctionDecl *Conversions
|
||||
= FromRecordDecl->getConversionFunctions();
|
||||
= FromRecordDecl->getVisibleConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator Func
|
||||
= Conversions->function_begin();
|
||||
Func != Conversions->function_end(); ++Func) {
|
||||
|
@ -2427,7 +2426,11 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
|
|||
Candidate.Viable = true;
|
||||
Candidate.Conversions.resize(1);
|
||||
Candidate.Conversions[0] = TryObjectArgumentInitialization(From, Conversion);
|
||||
|
||||
// Conversion functions to a different type in the base class is visible in
|
||||
// the derived class. So, a derived to base conversion should not participate
|
||||
// in overload resolution.
|
||||
if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base)
|
||||
Candidate.Conversions[0].Standard.Second = ICK_Identity;
|
||||
if (Candidate.Conversions[0].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
Candidate.Viable = false;
|
||||
|
|
|
@ -77,12 +77,31 @@ int main() {
|
|||
g(o1, o2);
|
||||
}
|
||||
|
||||
// Test. Conversion in base class is visible in derived class.
|
||||
class XB {
|
||||
public:
|
||||
operator int();
|
||||
};
|
||||
|
||||
class Yb : public XB {
|
||||
public:
|
||||
operator char();
|
||||
};
|
||||
|
||||
void f(Yb& a) {
|
||||
int i = a; // OK. calls XB::operator int();
|
||||
char ch = a; // OK. calls Yb::operator char();
|
||||
}
|
||||
|
||||
|
||||
// CHECK-LP64: .globl __ZN1ScviEv
|
||||
// CHECK-LP64-NEXT: __ZN1ScviEv:
|
||||
// CHECK-LP64: call __ZN1Ycv1ZEv
|
||||
// CHECK-LP64: call __ZN1Zcv1XEv
|
||||
// CHECK-LP64: call __ZN1XcviEv
|
||||
// CHECK-LP64: call __ZN1XcvfEv
|
||||
// CHECK-LP64: call __ZN2XBcviEv
|
||||
// CHECK-LP64: call __ZN2YbcvcEv
|
||||
|
||||
// CHECK-LP32: .globl __ZN1ScviEv
|
||||
// CHECK-LP32-NEXT: __ZN1ScviEv:
|
||||
|
@ -90,3 +109,5 @@ int main() {
|
|||
// CHECK-LP32: call L__ZN1Zcv1XEv
|
||||
// CHECK-LP32: call L__ZN1XcviEv
|
||||
// CHECK-LP32: call L__ZN1XcvfEv
|
||||
// CHECK-LP32: call L__ZN2XBcviEv
|
||||
// CHECK-LP32: call L__ZN2YbcvcEv
|
||||
|
|
|
@ -75,3 +75,21 @@ C::operator const char*() const { return 0; }
|
|||
void f(const C& c) {
|
||||
const char* v = c;
|
||||
}
|
||||
|
||||
// Test. Conversion in base class is visible in derived class.
|
||||
class XB {
|
||||
public:
|
||||
operator int();
|
||||
};
|
||||
|
||||
class Yb : public XB {
|
||||
public:
|
||||
operator char();
|
||||
};
|
||||
|
||||
void f(Yb& a) {
|
||||
if (a) { } // expected-error {{value of type 'class Yb' is not contextually convertible to 'bool'}}
|
||||
int i = a; // OK. calls XB::operator int();
|
||||
char ch = a; // OK. calls Yb::operator char();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue