Fixed a code gen bug (by fixing the AST) involving user-defined

pointer-to-member type conversion follwed by a pointer-to-member
standard conversion.

llvm-svn: 84955
This commit is contained in:
Fariborz Jahanian 2009-10-23 18:08:22 +00:00
parent 4ef112be62
commit c9af8fd76b
2 changed files with 57 additions and 0 deletions

View File

@ -1140,6 +1140,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor);
}
if (ICS.UserDefined.After.Second == ICK_Pointer_Member &&
ToType.getNonReferenceType()->isMemberFunctionPointerType())
CastKind = CastExpr::CK_BaseToDerivedMemberPointer;
From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
CastKind, CastArg.takeAs<Expr>(),
ToType->isLValueReferenceType());

View File

@ -0,0 +1,53 @@
// 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
// 13.3.3.2 Ranking implicit conversion sequences
extern "C" int printf(...);
struct A {
int Ai;
};
struct B : public A {
void bf() { printf("B::bf called\n"); }
};
struct C : public B { };
// conversion of B::* to C::* is better than conversion of A::* to C::*
typedef void (A::*pmfa)();
typedef void (B::*pmfb)();
typedef void (C::*pmfc)();
struct X {
operator pmfa();
operator pmfb() {
return &B::bf;
}
};
void g(pmfc pm) {
C c;
(c.*pm)();
}
void test2(X x)
{
g(x);
}
int main()
{
X x;
test2(x);
}
// CHECK-LP64: call __ZN1XcvM1BFvvEEv
// CHECK-LP64: call __Z1gM1CFvvE
// CHECK-LP32: call L__ZN1XcvM1BFvvEEv
// CHECK-LP32: call __Z1gM1CFvvE